home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-02-13 | 82.8 KB | 3,709 lines |
- Newsgroups: comp.sources.misc
- subject: v10i060: An 8031/8051 Assembler
- From: stauffer@cpsc.ucalgary.ca (Kenneth Stauffer)
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 10, Issue 60
- Submitted-by: stauffer@cpsc.ucalgary.ca (Kenneth Stauffer)
- Archive-name: asm.8051
-
- This is an 8031/8051 Assembler, which generates
- many different output formats including S-records.
-
- Ken Stauffer.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: README as31.h as31.y as31.man emitter.c lexer.c main.c
- # makefile symbol.c new.asm
- # Wrapped by stauffer@cpsc.UCalgary.CA on Tue Jan 30 18:35:17 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1528 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X
- X
- X as31 - An 8031/8051 assembler.
- X
- X Written by:
- X K e n S t a u f f e r
- X
- X
- Xas31, is an 8031/8051 assembler. The program consists of the
- Xfollowing files:
- X
- X makefile - Makefile.
- X as31.h - Package header file.
- X as31.y - Parser / code generator.
- X lexer.c - Scanner.
- X symbol.c - Symbol table / opcode table.
- X emitter.c - Object code generation routines.
- X main.c - Command line / calls yyparse().
- X
- X as31.man - Assembler manual.
- X
- X new.asm - Sample 8031 code. This is a working
- X debugger written by Theo Deraadt.
- X
- XOVERVIEW OF AS31:
- X as31 is a full featured assembler but it does lack
- X facilities for linking several modules together.
- X as31 can be configured to produced a wide variety of
- X object output formats.
- X One of the supported output formats is S-records.
- X (Written by: Theo Deraadt)
- X
- X Standard assembler syntax is accepted.
- X
- XMAKING AS31:
- X On most unix systems, running make should be sufficient
- X to produce a working assembler.
- X
- X Also typing:
- X
- X % make man
- X
- X Will produces a text file from as31.man (called as31.cat).
- X This is the users manual.
- X
- X This package does work on the following systems:
- X SUN 3 / SUN 4 (SunOS 4.0), Tandy 6000 (Xenix)
- X
- X Non-unix systems may require some porting for the FILE I/O
- X stuff but most reasonable implementations of stdio.h
- X should work.
- X
- XSOURCE CODE:
- X This code is public domain.
- X
- XREPORTING BUGS:
- X If any bugs are detected in this program, I would
- X like to know about them so that I could fix them. I can
- X be reached via E-mail at:
- X
- X stauffer@cpsc.ucalgary.ca
- X
- XJanuary 26, 1990
- X
- END_OF_FILE
- if test 1528 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'as31.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'as31.h'\"
- else
- echo shar: Extracting \"'as31.h'\" \(3549 characters\)
- sed "s/^X//" >'as31.h' <<'END_OF_FILE'
- X/* ----------------------------------------------------------------------
- X * FILE: as31.h
- X * PACKAGE: as31 - 8031/8051 Assembler.
- X *
- X * DESCRIPTION:
- X * The sole header file for the 8031/8051 assembler package.
- X * It defines several structures used by the yacc stack.
- X * It defines several macros for testing the bitsize of numeric
- X * quantities.
- X *
- X * Some macros to extract information from the mode structure.
- X *
- X * REVISION HISTORY:
- X * Jan. 19, 1990 - Created. (Ken Stauffer)
- X *
- X * AUTHOR:
- X * All code in this file written by Ken Stauffer (University of Calgary).
- X * January, 1990.
- X *
- X */
- X
- X/* ----------------------------------------------------------------------
- X * user / keyword symbol structures:
- X */
- X
- Xstruct opcode {
- X char *name;
- X int type;
- X unsigned char *bytes;
- X};
- X
- Xstruct symbol {
- X char *name;
- X int type;
- X long value;
- X struct symbol *next;
- X};
- X
- X#define UNDEF 0
- X#define LABEL 1
- X
- X/* ----------------------------------------------------------------------
- X * addressing mode stuff:
- X */
- X
- Xstruct mode {
- X unsigned char mode; /* value to index with */
- X unsigned char size; /* # of bytes used */
- X unsigned char orval; /* value OR'd to obcode */
- X unsigned char byte1; /* extra byte 1 */
- X unsigned char byte2; /* extra byte 2 */
- X};
- X
- X#define set_md(m,a) ((m).mode=(a))
- X#define set_sz(m,a) ((m).size=(a))
- X#define set_ov(m,a) ((m).orval=(a))
- X#define set_b1(m,a) ((m).byte1=(a))
- X#define set_b2(m,a) ((m).byte2=(a))
- X
- X#define get_md(m) ((m).mode)
- X#define get_sz(m) ((m).size)
- X#define get_ov(m) ((m).orval)
- X#define get_b1(m) ((m).byte1)
- X#define get_b2(m) ((m).byte2)
- X
- X/* ----------------------------------------------------------------------
- X * yacc stack stuff:
- X */
- X
- Xstruct value {
- X long v;
- X unsigned char d; /* expression defined flag */
- X};
- X
- Xunion ystack {
- X long value;
- X struct value val;
- X struct opcode *op;
- X struct symbol *sym;
- X struct mode mode;
- X char *str;
- X};
- X
- X/* ----------------------------------------------------------------------
- X * IS_BIT_MAPPED_RAM:
- X * True is the byte 'a' is the byte address of a bit mapped
- X * RAM location.
- X */
- X#define isbmram(a) (((a)&0xf0)==0x20)
- X
- X/* ----------------------------------------------------------------------
- X * IS_BIT_MAPPED_SFR:
- X * True is the byte 'a' is the byte address of a bit mapped
- X * SPECIAL FUCTION REGISTER.
- X */
- X#define isbmsfr(a) (((a)&0x80) && !((a) & 0x07))
- X
- X/* ----------------------------------------------------------------------
- X * isbit8, ...
- X * Macros to check the sizes of values and to convert
- X * a value to a certain, size.
- X *
- X */
- X#define size8 (~0x00ff)
- X#define size11 (~0x07ff)
- X#define size13 (~0x1fff)
- X#define size16 (~0xffff)
- X
- X#define size10 (~0x03ff)
- X#define size12 (~0x0fff)
- X#define size15 (~0x7fff)
- X
- X#define isbit8(v) ( !( ((v)>=0) ? (v)&size8 : -(v)>=128) )
- X#define isbit11(v) ( !( ((v)>=0) ? (v)&size11 : (-(v))&size10 ) )
- X#define isbit13(v) ( !( ((v)>=0) ? (v)&size13 : (-(v))&size12 ) )
- X#define isbit16(v) ( !( ((v)>=0) ? (v)&size16 : (-(v))&size15 ) )
- X
- X/* ----------------------------------------------------------------------
- X * Size of user hash table.
- X */
- X#define HASHTABSIZE 1000
- X
- X/* ----------------------------------------------------------------------
- X * Macros to nicely test which pass we are in.
- X */
- X#define pass1 (!pass)
- X#define pass2 (pass)
- X
- X/* -------- TOKENS ------------------------------------------------------
- X *
- X * This includes the header file generated by yacc -d.
- X * NOPE is defined inside of as31.y, which does not
- X * need to re-include the tokens twice, thus NOPE prevents this.
- X *
- X */
- X#ifdef NOPE
- X#else
- X#include "y.tab.h"
- X#endif
- X
- END_OF_FILE
- if test 3549 -ne `wc -c <'as31.h'`; then
- echo shar: \"'as31.h'\" unpacked with wrong size!
- fi
- # end of 'as31.h'
- fi
- if test -f 'as31.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'as31.y'\"
- else
- echo shar: Extracting \"'as31.y'\" \(22290 characters\)
- sed "s/^X//" >'as31.y' <<'END_OF_FILE'
- X/* ----------------------------------------------------------------------
- X * FILE: as31.y
- X * PACKAGE: as31 - 8031/8051 Assembler.
- X *
- X * DESCRIPTION:
- X * This file contains the yacc parser for the assembler.
- X * Related to this are the following:
- X * error(), warning(), yyerror()
- X * genbyte(), genword(), genstr(), makeop()
- X *
- X *
- X * REVISION HISTORY:
- X * Jan. 19, 1990 - Created. (Ken Stauffer)
- X *
- X * AUTHOR:
- X * All code in this file written by Ken Stauffer (University of Calgary).
- X * January 1990.
- X *
- X */
- X
- X%{
- X
- X#include <setjmp.h>
- X#include <stdio.h>
- X#define NOPE
- X#include "as31.h"
- X#undef NOPE
- X
- X#define YYSTYPE union ystack
- X
- Xextern int lineno;
- Xextern int dashl;
- Xextern char *asmfile;
- Xextern jmp_buf main_env;
- Xextern FILE *listing;
- X
- Xint pass,fatal;
- Xunsigned long lc;
- X
- Xstatic unsigned char bytebuf[1024]; /* used by dumplist() */
- Xstatic int bytecount;
- X
- X/* ------------------------ G R A M M E R ----------------------------- */
- X
- X%}
- X
- X%token STRING
- X%token D_ORG
- X%token D_BYTE
- X%token D_WORD
- X%token D_SKIP
- X%token D_EQU
- X%token D_FLAG
- X%token D_END
- X%token ACALL
- X%token ADD
- X%token ADDC
- X%token AJMP
- X%token ANL
- X%token CJNE
- X%token CLR
- X%token CPL
- X%token DA
- X%token DEC
- X%token DIV
- X%token DJNZ
- X%token INC
- X%token JB
- X%token JBC
- X%token JC
- X%token JMP
- X%token JNB
- X%token JNC
- X%token JNZ
- X%token JZ
- X%token LCALL
- X%token LJMP
- X%token MOV
- X%token MOVC
- X%token MOVX
- X%token NOP
- X%token MUL
- X%token ORL
- X%token POP
- X%token PUSH
- X%token RET
- X%token RETI
- X%token RL
- X%token RLC
- X%token RR
- X%token RRC
- X%token SETB
- X%token SJMP
- X%token SUBB
- X%token SWAP
- X%token XCH
- X%token XCHD
- X%token XRL
- X%token AB
- X%token A
- X%token C
- X%token PC
- X%token DPTR
- X%token BITPOS
- X%token R0
- X%token R1
- X%token R2
- X%token R3
- X%token R4
- X%token R5
- X%token R6
- X%token R7
- X%token VALUE
- X%token SYMBOL
- X
- X%left '+' '-'
- X%left '*' '/' '%'
- X%left '|' '&'
- X
- X%start program
- X
- X%%
- Xprogram : linelist
- X{
- X}
- X ;
- X
- Xlinelist : linelist line
- X | line
- X ;
- X
- Xline : undefsym ':' linerest
- X{
- X if( pass1 ) {
- X $1.sym->type = LABEL;
- X $1.sym->value = lc;
- X }
- X inclc($3.value);
- X bytecount = 0;
- X}
- X | linerest { inclc($1.value); bytecount = 0; }
- X ;
- X
- Xlinerest : directive '\n' {
- X $$.value = $1.value;
- X if( dashl && pass2 )
- X dumplist($2.str,1);
- X }
- X | instr '\n' {
- X $$.value = $1.value;
- X if( dashl && pass2 )
- X dumplist($2.str,1);
- X
- X }
- X | '\n' {
- X $$.value = 0;
- X if( dashl && pass2 )
- X dumplist($1.str,0);
- X }
- X ;
- X
- X
- X
- X
- X
- X/* --------------------
- X * DIRECTIVES:
- X *
- X */
- X
- Xdirective : '.' D_ORG defexpr
- X{
- X lc = $3.val.v;
- X if( pass2 ) emitaddr(lc);
- X bytecount = 0;
- X $$.value = 0;
- X}
- X | '.' D_BYTE blist { $$.value = $3.value; }
- X | '.' D_WORD wlist { $$.value = $3.value; }
- X | '.' D_SKIP defexpr { $$.value = $3.val.v;
- X if( pass2 )
- X emitaddr(lc+$$.value); }
- X | '.' D_EQU undefsym ',' expr
- X{
- X if( $5.val.d == 0 )
- X error("Expression is undefined in pass 1");
- X $3.sym->type = LABEL;
- X $3.sym->value = $5.val.v;
- X $$.value = 0;
- X}
- X
- X | '.' D_FLAG SYMBOL ',' flag
- X{
- X $3.sym->type = LABEL;
- X $3.sym->value = $5.value;
- X $$.value = 0;
- X}
- X | '.' D_END { $$.value = 0; }
- X ;
- X
- Xdefexpr : expr
- X{
- X if( $1.val.d == 0 )
- X error("Expression is undefined in pass 1");
- X if( !(isbit16($1.val.v)) )
- X error("Value greater than 16-bits");
- X $$.value = $1.val.v;
- X}
- X ;
- X
- Xflag : flagv BITPOS
- X{
- X if( !isbit8($1.value) )
- X warning("Bit address exceeds 8-bits");
- X if( isbmram($1.value) )
- X $$.value = ($1.value-0x20)*8+ $2.value;
- X else if( isbmsfr($1.value) )
- X $$.value = $1.value + $2.value;
- X else
- X warning("Invalid bit addressable RAM location");
- X}
- X ;
- X
- Xflagv : SYMBOL
- X{
- X if( $1.sym->type == UNDEF )
- X error("Symbol %s must be defined in pass 1",$1.sym->name);
- X $$.value = $1.sym->value;
- X}
- X | VALUE { $$.value = $1.value; }
- X ;
- X
- X
- Xundefsym : SYMBOL
- X{
- X if( $1.sym->type != UNDEF && pass1)
- X error("Attempt to redefine symbol: %s",$1.sym->name);
- X $$.sym = $1.sym;
- X}
- X ;
- X
- Xblist : blist ',' data8
- X{
- X if( pass2 ) genbyte($3.value);
- X $$.value = $1.value + 1;
- X}
- X | blist ',' STRING
- X{
- X if( pass1 )
- X $$.value = $1.value + $3.value;
- X else {
- X $$.value = $1.value + strlen($3.str);
- X genstr($3.str);
- X
- X free($3.str);
- X }
- X}
- X | data8
- X{
- X if( pass2 ) genbyte($1.value);
- X $$.value = 1;
- X}
- X | STRING
- X{
- X if( pass1 )
- X $$.value = $1.value;
- X else {
- X $$.value = strlen($1.str);
- X genstr($1.str);
- X free($1.str);
- X }
- X}
- X ;
- X
- Xwlist : wlist ',' data16
- X{
- X if( pass2 ) genword($3.value);
- X $$.value = $1.value + 2;
- X}
- X | data16
- X{
- X if( pass2 ) genword($1.value);
- X $$.value = 2;
- X}
- X ;
- X
- X
- X
- X/* --------------------
- X * EXPRESSIONS:
- X *
- X */
- X
- Xexpr : '*' { $$.val.v = lc;
- X $$.val.d = 1; }
- X
- X | '(' expr ')' { $$.val.v = $2.val.v;
- X $$.val.d = $2.val.d; }
- X
- X | '-' expr %prec '*' { $$.val.v = -$2.val.v;
- X $$.val.d = $2.val.d; }
- X
- X | expr '|' expr { $$.val.v = $1.val.v | $3.val.v;
- X $$.val.d = $1.val.d && $3.val.d; }
- X
- X | expr '&' expr { $$.val.v = $1.val.v & $3.val.v;
- X $$.val.d = $1.val.d && $3.val.d; }
- X
- X | expr '*' expr { $$.val.v = $1.val.v * $3.val.v;
- X $$.val.d = $1.val.d && $3.val.d; }
- X
- X | expr '/' expr { $$.val.v = $1.val.v / $3.val.v;
- X $$.val.d = $1.val.d && $3.val.d; }
- X
- X | expr '%' expr { $$.val.v = $1.val.v % $3.val.v;
- X $$.val.d = $1.val.d && $3.val.d; }
- X
- X | expr '-' expr { $$.val.v = $1.val.v - $3.val.v;
- X $$.val.d = $1.val.d && $3.val.d; }
- X
- X | expr '+' expr { $$.val.v = $1.val.v + $3.val.v;
- X $$.val.d = $1.val.d && $3.val.d; }
- X | SYMBOL
- X{
- X if( pass1 ) {
- X $$.val.v = $1.sym->value;
- X $$.val.d = ($1.sym->type != UNDEF);
- X }
- X else {
- X if( $1.sym->type == UNDEF )
- X error("Undefined symbol %s",$1.sym->name);
- X $$.val.v = $1.sym->value;
- X $$.val.d = 1;
- X }
- X}
- X | VALUE { $$.val.v = $1.val.v; $$.val.d=1; }
- X ;
- X
- X
- X
- X
- X
- X/* --------------------
- X * INSTRUCTIONS:
- X *
- X */
- X
- Xinstr : NOP
- X { $$.value = makeop($1.op,NULL,0); }
- X | ACALL addr11
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | AJMP addr11
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | ADD two_op1
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | ADDC two_op1
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | SUBB two_op1
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | XRL two_op1
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | XRL two_op2
- X { $$.value = makeop($1.op,&$2.mode,4); }
- X | ANL two_op1
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | ANL two_op2
- X { $$.value = makeop($1.op,&$2.mode,4); }
- X | ANL two_op3
- X { $$.value = makeop($1.op,&$2.mode,6); }
- X | ORL two_op1
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | ORL two_op2
- X { $$.value = makeop($1.op,&$2.mode,4); }
- X | ORL two_op3
- X { $$.value = makeop($1.op,&$2.mode,6); }
- X | XCH two_op1
- X { if( get_md($2.mode) == 3 )
- X error("Immediate mode is illegal");
- X $$.value = makeop($1.op,&$2.mode,0);
- X }
- X | INC single_op1
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | INC DPTR
- X { $$.value = makeop($1.op,NULL,4); }
- X | DEC single_op1
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | DA A
- X { $$.value = makeop($1.op,NULL,0); }
- X | DIV AB
- X { $$.value = makeop($1.op,NULL,0); }
- X | JMP '@' A '+' DPTR
- X { $$.value = makeop($1.op,NULL,0); }
- X | JMP '@' DPTR '+' A
- X { $$.value = makeop($1.op,NULL,0); }
- X | MUL AB
- X { $$.value = makeop($1.op,NULL,0); }
- X | RET
- X { $$.value = makeop($1.op,NULL,0); }
- X | RETI
- X { $$.value = makeop($1.op,NULL,0); }
- X | RL A
- X { $$.value = makeop($1.op,NULL,0); }
- X | RLC A
- X { $$.value = makeop($1.op,NULL,0); }
- X | RR A
- X { $$.value = makeop($1.op,NULL,0); }
- X | RRC A
- X { $$.value = makeop($1.op,NULL,0); }
- X | SWAP A
- X { $$.value = makeop($1.op,NULL,0); }
- X | XCHD two_op1
- X { if( get_md($2.mode) != 2 )
- X error("Invalid addressing mode");
- X $$.value = makeop($1.op,&$2.mode,-2); }
- X | CLR single_op2
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | CPL single_op2
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | SETB single_op2
- X { if( get_md($2.mode) == 0 )
- X error("Invalid addressing mode");
- X $$.value = makeop($1.op,&$2.mode,-1); }
- X | PUSH data8
- X {
- X struct mode tmp;
- X set_md(tmp,0);
- X set_ov(tmp,0);
- X set_sz(tmp,1);
- X set_b1(tmp,$2.value);
- X $$.value = makeop($1.op,&tmp,0);
- X }
- X | POP data8
- X {
- X struct mode tmp;
- X set_md(tmp,0);
- X set_ov(tmp,0);
- X set_sz(tmp,1);
- X set_b1(tmp,$2.value);
- X $$.value = makeop($1.op,&tmp,0);
- X }
- X | LJMP addr16
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | LCALL addr16
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | JC relative
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | JNC relative
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | JNZ relative
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | JZ relative
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | SJMP relative
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | CJNE three_op1
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | JB two_op4
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | JNB two_op4
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | JBC two_op4
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | DJNZ two_op5
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | MOV two_op1
- X { $$.value = makeop($1.op,&$2.mode,0); }
- X | MOV two_op2
- X { $$.value = makeop($1.op,&$2.mode,4); }
- X | MOV two_op6
- X { $$.value = makeop($1.op,&$2.mode,6); }
- X
- X
- X | MOVC A ',' '@' A '+' DPTR
- X { $$.value = makeop($1.op,NULL,0); }
- X | MOVC A ',' '@' DPTR '+' A
- X { $$.value = makeop($1.op,NULL,0); }
- X | MOVC A ',' '@' A '+' PC
- X { $$.value = makeop($1.op,NULL,1); }
- X | MOVC A ',' '@' PC '+' A
- X { $$.value = makeop($1.op,NULL,1); }
- X
- X | MOVX A ',' '@' regi
- X { $$.value = makeop($1.op,NULL,$5.value); }
- X | MOVX A ',' '@' DPTR
- X { $$.value = makeop($1.op,NULL,2); }
- X | MOVX '@' regi ',' A
- X { $$.value = makeop($1.op,NULL,$3.value+3); }
- X | MOVX '@' DPTR ',' A
- X { $$.value = makeop($1.op,NULL,5); }
- X ;
- X
- X
- X
- X
- X/* --------------------
- X * ADDRESSING MODES:
- X *
- X */
- X
- Xtwo_op1 : A ',' reg
- X {
- X set_md($$.mode,0);
- X set_ov($$.mode, $3.value);
- X set_sz($$.mode, 0);
- X }
- X | A ',' data8
- X {
- X set_md($$.mode,1);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$3.value);
- X }
- X | A ',' '@' regi
- X {
- X set_md($$.mode,2);
- X set_ov($$.mode,$4.value);
- X set_sz($$.mode,0);
- X }
- X | A ',' '#' data8
- X {
- X set_md($$.mode,3);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$4.value);
- X }
- X ;
- X
- Xtwo_op2 : data8 ',' A
- X {
- X set_md($$.mode,0);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$1.value);
- X }
- X | data8 ',' '#' data8
- X {
- X set_md($$.mode,1);
- X set_ov($$.mode,0);
- X set_sz($$.mode,2);
- X set_b1($$.mode,$1.value);
- X set_b2($$.mode,$4.value);
- X }
- X ;
- X
- Xtwo_op3 : C ',' bit
- X {
- X set_md($$.mode,0);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$3.value);
- X }
- X | C ',' '/' bit
- X {
- X set_md($$.mode,1);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$4.value);
- X }
- X | C ',' '!' bit
- X {
- X set_md($$.mode,1);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$4.value);
- X }
- X ;
- X
- Xtwo_op4 : bit ',' rel
- X {
- X set_md($$.mode,0);
- X set_ov($$.mode,0);
- X set_sz($$.mode,2);
- X set_b1($$.mode,$1.value);
- X set_b2($$.mode,$3.value);
- X }
- X ;
- X
- Xtwo_op5 : reg ',' rel2
- X {
- X set_md($$.mode,0);
- X set_ov($$.mode,$1.value);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$3.value);
- X }
- X | data8 ',' rel
- X {
- X set_md($$.mode,1);
- X set_ov($$.mode,0);
- X set_sz($$.mode,2);
- X set_b1($$.mode,$1.value);
- X set_b2($$.mode,$3.value);
- X }
- X ;
- X
- Xtwo_op6 : reg ',' A
- X {
- X set_md($$.mode,0);
- X set_ov($$.mode,$1.value);
- X set_sz($$.mode,0);
- X }
- X | reg ',' data8
- X {
- X set_md($$.mode,1);
- X set_ov($$.mode,$1.value);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$3.value);
- X }
- X | reg ',' '#' data8
- X {
- X set_md($$.mode,2);
- X set_ov($$.mode,$1.value);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$4.value);
- X }
- X | data8 ',' reg
- X {
- X set_md($$.mode,3);
- X set_ov($$.mode,$3.value);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$1.value);
- X }
- X | data8 ',' data8
- X {
- X set_md($$.mode,4);
- X set_ov($$.mode,0);
- X set_sz($$.mode,2);
- X set_b1($$.mode,$3.value);
- X set_b2($$.mode,$1.value);
- X }
- X | data8 ',' '@' regi
- X {
- X set_md($$.mode,5);
- X set_ov($$.mode,$4.value);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$1.value);
- X }
- X | '@' regi ',' A
- X {
- X set_md($$.mode,6);
- X set_ov($$.mode,$2.value);
- X set_sz($$.mode,0);
- X }
- X | '@' regi ',' data8
- X {
- X set_md($$.mode,7);
- X set_ov($$.mode,$2.value);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$4.value);
- X }
- X | '@' regi ',' '#' data8
- X {
- X set_md($$.mode,8);
- X set_ov($$.mode,$2.value);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$5.value);
- X }
- X | DPTR ',' '#' data16
- X {
- X set_md($$.mode,9);
- X set_ov($$.mode,0);
- X set_sz($$.mode,2);
- X set_b1($$.mode, ($4.value & 0xff00) >> 8 );
- X set_b2($$.mode, ($4.value & 0x00ff) );
- X }
- X | C ',' bit
- X {
- X set_md($$.mode,10);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$3.value);
- X }
- X /*
- X * Following two productions cannot be represented by:
- X *
- X * bit ',' C
- X *
- X * Because yacc gives tons of reduce/reduce errors if
- X * that is attempted.
- X *
- X */
- X | data8 ',' C
- X {
- X set_md($$.mode,11);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$1.value);
- X }
- X | data8 BITPOS ',' C
- X{
- X if( pass2 ) {
- X if( !isbit8($1.value) )
- X warning("Bit address exceeds 8-bits");
- X if( isbmram($1.value) )
- X set_b1($$.mode, ($1.value-0x20)*8+ $2.value );
- X else if( isbmsfr($1.value) )
- X set_b1($$.mode, $1.value + $2.value );
- X else
- X warning("Invalid bit addressable RAM location");
- X }
- X set_md($$.mode,11);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X}
- X ;
- X
- X
- Xsingle_op1 : A
- X {
- X set_md($$.mode,0);
- X set_ov($$.mode,0);
- X set_sz($$.mode,0);
- X }
- X
- X | reg
- X {
- X set_md($$.mode,1);
- X set_ov($$.mode,$1.value);
- X set_sz($$.mode,0);
- X }
- X | data8
- X {
- X set_md($$.mode,2);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$1.value);
- X }
- X | '@' regi
- X {
- X set_md($$.mode,3);
- X set_ov($$.mode,$2.value);
- X set_sz($$.mode,0);
- X }
- X ;
- X
- Xsingle_op2 : A
- X {
- X set_md($$.mode,0);
- X set_ov($$.mode,0);
- X set_sz($$.mode,0);
- X }
- X | C
- X {
- X set_md($$.mode,1);
- X set_ov($$.mode,0);
- X set_sz($$.mode,0);
- X }
- X | bit
- X {
- X set_md($$.mode,2);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,$1.value);
- X }
- X ;
- X
- Xthree_op1 : A ',' data8 ',' rel
- X {
- X set_md($$.mode,0);
- X set_ov($$.mode,0);
- X set_sz($$.mode,2);
- X set_b1($$.mode,$3.value);
- X set_b2($$.mode,$5.value);
- X }
- X | A ',' '#' data8 ',' rel
- X {
- X set_md($$.mode,1);
- X set_ov($$.mode,0);
- X set_sz($$.mode,2);
- X set_b1($$.mode,$4.value);
- X set_b2($$.mode,$6.value);
- X }
- X | reg ',' '#' data8 ',' rel
- X {
- X set_md($$.mode,2);
- X set_ov($$.mode,$1.value);
- X set_sz($$.mode,2);
- X set_b1($$.mode,$4.value);
- X set_b2($$.mode,$6.value);
- X }
- X | '@' regi ',' '#' data8 ',' rel
- X {
- X set_md($$.mode,3);
- X set_ov($$.mode,$2.value);
- X set_sz($$.mode,2);
- X set_b1($$.mode,$5.value);
- X set_b2($$.mode,$7.value);
- X }
- X ;
- X
- Xrel : expr
- X{
- X long offset;
- X if( pass2 ) {
- X offset = $1.val.v - (lc+3);
- X if( offset > 127 || offset < -128 )
- X warning("Relative offset exceeds -128 / +127");
- X $$.value = offset;
- X }
- X}
- X ;
- X
- X/*
- X * This production differs from the above, by 1 number!
- X *
- X */
- X
- Xrel2 : expr
- X{
- X long offset;
- X if( pass2 ) {
- X offset = $1.val.v - (lc+2); /* different! */
- X if( offset > 127 || offset < -128 )
- X warning("Relative offset exceeds -128 / +127");
- X $$.value = offset;
- X }
- X}
- X ;
- X
- X
- Xbit : bitv BITPOS
- X{
- X if( pass2 ) {
- X if( !isbit8($1.value) )
- X warning("Bit address exceeds 8-bits");
- X if( isbmram($1.value) )
- X $$.value = ($1.value-0x20)*8+$2.value;
- X else if( isbmsfr($1.value) )
- X $$.value = $1.value + $2.value;
- X else
- X warning("Invalid bit addressable RAM location");
- X }
- X}
- X | bitv
- X{
- X if( pass2 ) {
- X if( !isbit8($1.value) )
- X warning("Bit address exceeds 8-bits");
- X $$.value = $1.value;
- X }
- X}
- X ;
- X
- Xbitv : SYMBOL
- X{
- X if( $1.sym->type == UNDEF && pass2 )
- X error("Symbol %s undefined",$1.sym->name);
- X $$.value = $1.sym->value;
- X}
- X | VALUE { $$.value = $1.value; }
- X ;
- X
- Xreg : R0 { $$.value = 0; }
- X | R1 { $$.value = 1; }
- X | R2 { $$.value = 2; }
- X | R3 { $$.value = 3; }
- X | R4 { $$.value = 4; }
- X | R5 { $$.value = 5; }
- X | R6 { $$.value = 6; }
- X | R7 { $$.value = 7; }
- X ;
- X
- Xregi : R0 { $$.value = 0; }
- X | R1 { $$.value = 1; }
- X | R2
- X { $$.value = 0;
- X warning("Illegal indirect register: @r2"); }
- X | R3
- X { $$.value = 0;
- X warning("Illegal indirect register: @r3"); }
- X | R4
- X { $$.value = 0;
- X warning("Illegal indirect register: @r4"); }
- X | R5
- X { $$.value = 0;
- X warning("Illegal indirect register: @r5"); }
- X | R6
- X { $$.value = 0;
- X warning("Illegal indirect register: @r6"); }
- X | R7
- X { $$.value = 0;
- X warning("Illegal indirect register: @r7"); }
- X ;
- X
- Xdata8 : expr
- X{
- X if( pass2 ) {
- X if( !isbit8($1.val.v) )
- X warning("Expression greater than 8-bits");
- X }
- X $$.value = $1.val.v;
- X}
- X ;
- X
- Xdata16 : expr
- X{
- X if( pass2 ) {
- X if( !isbit16($1.val.v) )
- X warning("Expression greater than 16-bits");
- X }
- X $$.value = $1.val.v;
- X}
- X ;
- X
- Xaddr11 : expr
- X{
- X if( pass2 ) {
- X if( !isbit16($1.val.v) )
- X warning("Address greater than 16-bits");
- X if( ($1.val.v & size11) != ((lc+2) & size11) )
- X warning("Address outside current 2K page");
- X }
- X set_md($$.mode,0);
- X set_ov($$.mode, ($1.val.v&0x0700)>>3 );
- X set_sz($$.mode,1);
- X set_b1($$.mode,$1.val.v&0x00ff);
- X}
- X ;
- X
- Xaddr16 : expr
- X{
- X if( pass2 ) {
- X if( !isbit16($1.val.v) )
- X warning("Address greater than 16-bits");
- X }
- X set_md($$.mode,0);
- X set_ov($$.mode, 0 );
- X set_sz($$.mode,2);
- X set_b1($$.mode, ($1.val.v & 0xff00 ) >> 8 );
- X set_b2($$.mode, ($1.val.v & 0x00ff ) );
- X}
- X ;
- X
- Xrelative : expr
- X{
- X long offset;
- X if( pass2 ) {
- X offset = $1.val.v - (lc+2);
- X if( offset>127 || offset<-128 )
- X warning("Relative offset exceeds -128 / +127");
- X }
- X set_md($$.mode,0);
- X set_ov($$.mode,0);
- X set_sz($$.mode,1);
- X set_b1($$.mode,offset);
- X
- X}
- X ;
- X
- X%%
- X
- X/* ---------------------------------------------------------------------- */
- X
- Xyyerror(s)
- Xchar *s;
- X{
- X error(s);
- X}
- X
- X
- X/* ----------------------------------------------------------------------
- X * error:
- X * Uses semi-variable arguments. This causes immediate assembler
- X * termination.
- X */
- X
- Xerror(cs,a1,a2,a3,a4,a5,a6)
- Xchar *cs,*a1,*a2,*a3,*a4,*a5,*a6;
- X{
- X fprintf(stderr,"File: %s, line: %d, ",asmfile,lineno);
- X fprintf(stderr,cs,a1,a2,a3,a4,a5,a6);
- X fprintf(stderr,".\n");
- X longjmp(main_env,1);
- X}
- X
- X/* ----------------------------------------------------------------------
- X * warning:
- X * Produce error message. This will abort assembly at
- X * the end of the current pass.
- X *
- X */
- X
- Xwarning(cs,a1,a2,a3,a4,a5,a6)
- Xchar *cs,*a1,*a2,*a3,*a4,*a5,*a6;
- X{
- X fatal++;
- X fprintf(stderr,"File: %s, line: %d, ",asmfile,lineno);
- X fprintf(stderr,cs,a1,a2,a3,a4,a5,a6);
- X fprintf(stderr,".\n");
- X}
- X
- X
- X/* ----------------------------------------------------------------------
- X * makeop:
- X * This function makes an opcode based on the instruction symbol table
- X * entry, and an addressing mode structure.
- X * This function is called from both passes, but
- X * only generates code in pass 2.
- X *
- X * Resultant opcode bytes are passed to genbyte().
- X *
- X * Returns the nuumber of bytes that the instruction
- X * occupies.
- X *
- X */
- X
- Xmakeop(op,m,add)
- Xstruct opcode *op;
- Xstruct mode *m;
- X{
- X register unsigned int newop;
- X
- X if( m == NULL ) {
- X if(pass2) genbyte(op->bytes[0+add]);
- X return(1);
- X }
- X
- X if( pass2 ) {
- X newop = op->bytes[ get_md(*m)+add ] | get_ov(*m);
- X genbyte(newop);
- X if( get_sz(*m) > 0 ) genbyte( get_b1(*m) );
- X if( get_sz(*m) > 1 ) genbyte( get_b2(*m) );
- X }
- X return( get_sz(*m)+1 );
- X}
- X
- X
- X/* ----------------------------------------------------------------------
- X * inclc:
- X * Increments the Location Counter by 'i' amount.
- X * Check to see if 'i' overflows 64K.
- X * Checks to see if assembler is overlapping previous sections
- X * of code. (using a large bit field).
- X *
- X */
- X
- X#define indx(a) ( (a)/(sizeof(long)*8) )
- X#define bit(a) ( 1 << ((a)%(sizeof(long)*8)) )
- X
- X#define getloc(a) (regions[indx(a)] & bit(a))
- X#define setloc(a) (regions[indx(a)] |= bit(a))
- X
- Xinclc(i)
- X{
- X static unsigned long regions[ 0x10000/(sizeof(long)*8) ];
- X
- X while(i-- > 0) {
- X if( pass2 && getloc(lc) )
- X error("Location counter overlaps");
- X if( pass2 ) setloc(lc);
- X lc += 1;
- X }
- X
- X if( lc > 0xffff )
- X error("Location counter has exceeded 16-bits");
- X}
- X
- X/* ----------------------------------------------------------------------
- X * padline:
- X * This routine returns a new string, which is equivilant to
- X * 'line' except that all tabs have been expanded to spaces, and
- X * the total length has been truncated to 60 chars.
- X */
- X
- Xchar *padline(line)
- Xchar *line;
- X{
- X static char newline[61];
- X char *p1;
- X int pos=0,nxtpos;
- X
- X for(p1=line; pos<sizeof(newline)-1 && *p1; p1++ ) {
- X if( *p1 == '\t' ) {
- X nxtpos = pos+8-pos%8;
- X while(pos<sizeof(newline)-1 && pos <= nxtpos)
- X newline[pos++] = ' ';
- X } else if( *p1 != '\n' )
- X newline[pos++]= *p1;
- X }
- X newline[pos] = '\0';
- X return(newline);
- X}
- X
- X
- X/* ----------------------------------------------------------------------
- X * dumplist:
- X * Outputs the current location counter, bytebuf[] array, and
- X * the string 'txt' to the listing file.
- X * This routine is called for every source line encountered in the
- X * source file. (Only in pass 2, and if listing is turned on).
- X *
- X */
- X
- Xdumplist(txt,show)
- Xchar *txt;
- X{
- X int i,j;
- X
- X fprintf(listing,show?"%04X: ":" ",lc);
- X
- X j=0;
- X for(i=0; i<bytecount; i++ ) {
- X fprintf(listing,"%02X ",bytebuf[i]);
- X if( ++j >= 4 ) {
- X j = 0;
- X fprintf(listing,"\n ");
- X }
- X }
- X while(++j <= 4)
- X fprintf(listing," ");
- X
- X fprintf(listing," %s\n",padline(txt));
- X}
- X
- X/* ----------------------------------------------------------------------
- X * gen* routines:
- X * Place information into the bytebuf[] array, and also
- X * call emitbyte with the byte.
- X *
- X */
- X
- Xgenbyte(b)
- Xint b;
- X{
- X if( bytecount < sizeof(bytebuf) )
- X bytebuf[bytecount++] = b;
- X emitbyte(b);
- X}
- X
- Xgenstr(s)
- Xchar *s;
- X{
- X while( *s )
- X genbyte(*s++);
- X}
- X
- Xgenword(w)
- Xunsigned long w;
- X{
- X genbyte( (w & 0xff00) >> 8 );
- X genbyte( (w & 0x00ff) );
- X}
- X
- END_OF_FILE
- if test 22290 -ne `wc -c <'as31.y'`; then
- echo shar: \"'as31.y'\" unpacked with wrong size!
- fi
- # end of 'as31.y'
- fi
- if test -f 'as31.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'as31.man'\"
- else
- echo shar: Extracting \"'as31.man'\" \(9374 characters\)
- sed "s/^X//" >'as31.man' <<'END_OF_FILE'
- X.TH AS31 1L
- X.SH NAME
- Xas31 - An Intel 8031/8051 assembler
- X.SH SYNOPSIS
- X.B as31
- X[
- X.B \-Fformat
- X] [
- X.B \-Aarg
- X] [
- X.B \-l
- X]
- X.BR infile.asm
- X.SH DESCRIPTION
- X.I As31
- Xassembles
- X.IR infile.asm
- Xinto one of several different output formats. The output
- Xwill be in a file called infile.obj. The .asm extenstion
- Xis required.
- X
- X.SH OPTIONS
- XThe options must appear before the input file name. Both
- Xoptions are optional. The text of each flag must appear
- Xon the same argument as the flag. For example, "-Fod" is a
- Xvalid argument, but "-F od" is not.
- X.TP
- X.I \-Fformat
- XThis options specifies the output format that is to be used.
- X.IP
- XCurrently the only options available for this are:
- X.RS
- X.IP "tdr"
- XThis format generates an asci file of hex digits formatted in such a
- Xway, so that they can be read by tdr's debugger. An argument can be
- Xspecified (See -A option) which will pass a format specific string to
- Xthe format generator. In this case, the argument string represents
- Xan offset to add to the location counter. This offset is
- Xspecified in decimal and defaults to 64*1024 (0x10000). To specify
- Xand offset of 100, you would need "-Ftdr -A100" when invoking the
- Xassembler.
- X
- X.IP "byte"
- XThis format is simply an address and a byte on each line, in ascii.
- XNo -A option is used.
- X
- X.IP "od"
- XThis format is similar to the output from od(1). The format
- Xconsists of an address followed by sixteen hexadecimal bytes, followed
- Xby the equivilant ASCII. No -A option is used.
- X
- X.IP "srec2, srec3, srec4"
- XThe srecord generator is capable of generating output with any one
- Xof 2, 3, or 4 byte addresses. The -A option can be used to set the
- Xbase address offset, the default here is 0x0000 (unlike \fBtdr\fP).
- X.RE
- X.IP
- XNOTE: This assembler allows for the output formats to be expanded to
- Xinclude many different output formats.
- X.IP \-Aarg
- XThis option specifies a format specific string which is
- Xpassed to the format generator. Both format "tdr" and the srecord
- Xformats use this option.
- X.IP \-l
- XThis option tells the assembler to also generate a listing file.
- XA listing will be placed in the file infile.lst. Where 'infile' is
- Xthe file that is being assembled. This option may appear
- Xanywhere before infile.asm. The option must occur isolated on
- Xthe command line.
- X.IP
- XThe listing file shows the assembler generated code in hex, and up to
- X60 characters are retained from the source file.
- X.DE
- X
- X.SH "ASSEMBLER INSTRUCTIONS"
- XThis assembler accepts standard 8031/8051 instruction formats.
- XBelow is a list of instructions
- Xand addressing modes.
- X.IP
- X.RS
- X.nf
- X.ta +1i +2i +1i +1i
- XINSTRUCTION BYTES CYCLES
- X----------- ----- ------
- XACALL addr11 2 24
- XADD A, #data8 2 12
- XADD A, @Ri 1 12
- XADD A, Rn 1 12
- XADD A, direct 2 12
- XADDC A, #data8 2 12
- XADDC A, @Ri 1 12
- XADDC A, Rn 1 12
- XADDC A, direct 2 12
- XAJMP addr11 2 24
- XANL A, #data8 2 12
- XANL A, @Ri 1 12
- XANL A, Rn 1 12
- XANL A, direct 2 12
- XANL C, /bit 2 24
- XANL C, !bit 2 24
- XANL C, bit 2 24
- XANL direct, #data8 3 24
- XANL direct, A 2 12
- XCJNE @Ri, #data8, rel 3 24
- XCJNE A, #data8, rel 3 24
- XCJNE A, direct, rel 3 24
- XCJNE Rn, #data8, rel 3 24
- XCLR A 1 12
- XCLR C 1 12
- XCLR bit 2 12
- XCPL A 1 12
- XCPL C 1 12
- XCPL bit 2 12
- XDA A 1 12
- XDEC @Ri 1 12
- XDEC A 1 12
- XDEC DPTR 1 12
- XDEC Rn 1 12
- XDEC direct 2 12
- XDIV AB 1 48
- XDJNZ Rn, rel 2 24
- XDJNZ direct, rel 3 24
- XINC @Ri 1 12
- XINC A 1 12
- XINC DPTR 1 24
- XINC Rn 1 12
- XINC direct 2 12
- XJB bit, rel 3 24
- XJBC bit, rel 3 24
- XJC relative 2 24
- XJMP @A + DPTR 1 24
- XJMP @DPTR + A 1 24
- XJNB bit, rel 3 24
- XJNC relative 2 24
- XJNZ relative 2 24
- XJZ relative 2 24
- XLCALL addr16 3 24
- XLJMP addr16 3 24
- XMOV @Ri, #data8 2 12
- XMOV @Ri, A 1 12
- XMOV @Ri, direct 2 24
- XMOV A, #data8 2 12
- XMOV A, @Ri 1 12
- XMOV A, Rn 1 12
- XMOV A, direct 2 12
- XMOV C, bit 2 12
- XMOV DPTR, #data16 3 24
- XMOV Rn, #data8 2 12
- XMOV Rn, A 1 12
- XMOV Rn, direct 2 24
- XMOV bit, C 2 24
- XMOV direct, #data8 3 24
- XMOV direct, @Ri 2 24
- XMOV direct, A 2 12
- XMOV direct, Rn 2 24
- XMOV direct, direct 3 24
- XMOVC A, @A + DPTR 1 24
- XMOVC A, @A + PC 1 24
- XMOVC A, @DPTR + A 1 24
- XMOVC A, @PC + A 1 24
- XMOVX @DPTR, A 1 12
- XMOVX @Ri, A 1 24
- XMOVX A, @DPTR 1 24
- XMOVX A, @Ri 1 24
- XMUL AB 1 48
- XNOP 1 12
- XORL A, #data8 2 12
- XORL A, @Ri 1 12
- XORL A, Rn 1 12
- XORL A, direct 2 12
- XORL C, /bit 2 24
- XORL C, !bit 2 24
- XORL C, bit 2 24
- XORL direct, #data8 3 24
- XORL direct, A 2 12
- XPOP direct 2 24
- XPUSH direct 2 24
- XRET 1 24
- XRETI 1 24
- XRL A 1 12
- XRLC A 1 12
- XRR A 1 12
- XRRC A 1 12
- XSETB A 1 12
- XSETB bit 2 12
- XSJMP relative 2 24
- XSUBB A, #data8 2 12
- XSUBB A, @Ri 1 12
- XSUBB A, Rn 1 12
- XSUBB A, direct 2 12
- XSWAP A 1 12
- XXCH A, #data8 2 12
- XXCH A, @Ri 1 12
- XXCH A, Rn 1 12
- XXCH A, direct 2 12
- XXCHD A, #data8 2 12
- XXCHD A, @Ri 1 12
- XXCHD A, Rn 1 12
- XXCHD A, direct 2 12
- XXRL A, #data8 2 12
- XXRL A, @Ri 1 12
- XXRL A, Rn 1 12
- XXRL A, direct 2 12
- XXRL direct, #data8 3 12
- XXRL direct, A 2 12
- X.fi
- X.RE
- X
- X.SH "ASSEMBLER DIRECTIVES"
- XAs31 includes the following assembler directives:
- X.IP ".ORG expr"
- XStart assembling at the address specified by the expression expr.
- XAn error occurs if the assembler starts assembling over an address
- Xspace that has previously been assembled into.
- X
- X.IP ".EQU symbol, expr"
- XSet symbol to the value of expr. The value for expr must be
- Xknown during the first pass, when the line containing the .EQU
- Xis encountered.
- X
- X.IP ".BYTE expr, expr, ..."
- XAssemble the bytes specified by the expression into memory. A
- Xstring may also be specified with this directive.
- X
- X.IP ".WORD expr, expr, ..."
- XAssemble the words specified by the expression into memory.
- XThe byte ordering used, is that used by the 8031.
- X
- X.IP ".FLAG symbol1, symbol.[0-7]"
- XSets symbol1 to the bit address specified by the symbol.[0-7]
- Xexpression. Where [0-7] denotes a character between 0 and 7.
- XThe resulting bit address is checked to see if it is a valid bit
- Xaddress.
- X
- X.IP ".END"
- XThis directive is ignored.
- X
- X.IP ".SKIP expr"
- XAdds the value of expr to the location counter. Used
- Xto reserve a block of uninitialized data. Expr should
- Xbe in bytes.
- X
- X.SH "LEXICAL CONVENTIONS"
- X.IP "-"
- XAll characters following a semi-colon are ignored until a newline
- Xis encountered.
- X
- X.IP "-"
- XAll numbers default to decimal, unless the number starts with
- Xone of the following:
- X.RS
- X.IP "0x or 0X"
- XThis indicates a hexadecimal number. ie. 0x00ff
- X.IP "0b or 0B"
- XThis indicates a binary number. (1's and 0's). ie. 0b1100110010
- X.IP "0"
- XThis indicates an octal number. ie. 0377
- X.RE
- X.IP "-"
- XAll numbers default to decimal, unless the number ends with
- Xone of the following characters:
- X.RS
- X.IP "b or B"
- XThis indicates a binary number. Unless 0x was used above.
- Xie. 1010101b
- X.IP "h or H"
- XThis always indicates a hex number, However the if the first
- Xcharacter is non-numerical, then either 0x or 0 must be specified.
- XThis avoids confusing the assembler into thinking a hex number is
- Xa symbol.
- XFor example: 0ffh, 0xffh, 0XffH, 20h, 0x20 and 020h are means
- Xto specify a valid hexdigit. But the following are not:
- Xffh, 0ff.
- X.IP "d or D"
- XThis forces a number to decimal. Unless 0X was used. ie. 129d
- X.IP "o or O"
- XThis causes the number to be interpreted as octal. ie. 377o
- X.RE
- X
- X.IP "-"
- XA character constant can be entered as 'c' where c is some
- Xcharacter. \\b, \\n, \\r, \\t, \\' \\0 are also valid. A character
- Xconstant can be used anywhere that an integer value can.
- X
- X.IP "-"
- XA string is entered as a set of characters enclosed in double quotes "".
- XA string is only valid with the .BYTE directive. \\b, \\n, \\r, \\t, \\"
- Xare also valid escapes. However \\0 is not.
- X
- X.IP "-"
- XInstructions, directives, and the symbols: R0, R1, R2, R3, R4, R5,
- XR6, R7, A, AB, and C can be entered in upper or lower case without
- Xassembler confusion. These words however cannot be defined as a user symbol.
- XAny user symbol may be used, and case will be preserved. So the
- Xuser symbols "foo" and "Foo" are different, but "addc" is the same
- Xas "aDdC".
- X
- X.IP "-"
- XA symbol can be any alpha numerical character plus the underscore ('_').
- X
- X.IP "-"
- XExpressions are accepted in most places where a value or a symbol is
- Xneeded. An expression consists of the following operators. All
- Xoperators evaulate to integer objects (higher precedence opertors listed
- Xfirst):
- X.RS
- X.IP "-"
- XUnary minus
- X.IP "&"
- XBit-wise AND.
- X.IP "|"
- XBit-Wise OR.
- X.IP "*"
- XInteger multiplication.
- X.IP
- X\\ Integer division
- X.IP "%"
- XIntieger modulus
- X.IP "+"
- XInteger addition.
- X.IP "-"
- XInteger subtraction.
- X.RE
- X.IP "-"
- XIn addition to these operators, a special symbol '*' may be used
- Xto represent the current location counter.
- X
- X.SH EXAMPLES
- X.IP
- XBelow is a sample assembly program.
- X.RS
- X.nf
- X
- X .org 0
- Xstart: mov P3, #0xff ; use alternate fns on P3
- X ; leds on P1 are inverted.
- X setb F0 ; climbing up
- X mov A, #0x01 ; initial bit
- X
- Xwrite: cpl A ; write it
- X mov P1, A
- X cpl A
- X acall delay
- X jb F0, climbup ; climbing which way?
- X
- Xclimbdn: rr A ; down - shift right
- X jnb ACC.0, write ; back for more
- X setb F0
- X ajmp write
- X
- Xclimbup: rl A ; up - shift left
- X jnb ACC.7, write ; back for more
- X clr F0
- X ajmp write
- X .end ; this directive ignored.
- X.fi
- X
- X
- X.SH AUTHOR
- XKen Stauffer (University of Calgary)
- X.br
- Xstauffer@cpsc.ucalgary.ca
- END_OF_FILE
- if test 9374 -ne `wc -c <'as31.man'`; then
- echo shar: \"'as31.man'\" unpacked with wrong size!
- fi
- # end of 'as31.man'
- fi
- if test -f 'emitter.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'emitter.c'\"
- else
- echo shar: Extracting \"'emitter.c'\" \(8382 characters\)
- sed "s/^X//" >'emitter.c' <<'END_OF_FILE'
- X/* ----------------------------------------------------------------------
- X * FILE: emitter.c
- X * PACKAGE: as31 - 8031/8051 Assembler.
- X *
- X * DESCRIPTION:
- X * This file contains the code to generate various
- X * object code formats. Provisions exist to
- X * support many types of output formats within the
- X * same executable.
- X *
- X * REVISION HISTORY:
- X * Jan. 19, 1990 - Created. (Ken Stauffer)
- X * Jan. 29, 1990 - Added S-records (Theo Deraadt)
- X *
- X *
- X * AUTHOR:
- X * All code in this file written by Ken Stauffer (University of Calgary).
- X * January, 1990.
- X */
- X
- X#include <stdio.h>
- X
- X/* ----------------------------------------------------------------------
- X * DECLARE your own open(), close(), addr(), and byte() routines here.
- X *
- X */
- X
- Xstatic int open1(), close1(), addr1(), byte1();
- Xstatic int open2(), close2(), addr2(), byte2();
- Xstatic int open3(), close3(), addr3(), byte3();
- Xstatic int open4(), close4(), addr4(), byte4();
- X
- X/* ----------------------------------------------------------------------
- X * ADD an entry to this table to register your
- X * output format routines. Give your object format
- X * a name to be specified with the -F option.
- X *
- X */
- X
- Xstatic int format;
- Xstatic struct {
- X char *name;
- X int (*e_open)();
- X int (*e_close)();
- X int (*e_addr)();
- X int (*e_byte)();
- X} formtab[] = {
- X { "tdr", open1, close1, addr1, byte1 },
- X { "byte", open2, close2, addr2, byte2 },
- X { "od", open3, close3, addr3, byte3 },
- X { "srec2", open4, close4, addr4, byte4 },
- X { "srec3", open4, close4, addr4, byte4 },
- X { "srec4", open4, close4, addr4, byte4 }
- X};
- X
- X#define FORMTABSIZE (sizeof(formtab)/sizeof(formtab[0]))
- X
- Xemitusage()
- X{
- X int i;
- X fprintf(stderr, "\tfmt is one of:");
- X for(i=0; i<FORMTABSIZE; ) {
- X fprintf(stderr, "%s", formtab[i].name);
- X if( ++i < FORMTABSIZE)
- X fprintf(stderr, ", ");
- X }
- X fprintf(stderr, ".\n");
- X}
- X
- Xemitopen(file,ftype,arg)
- Xchar *file,*ftype,*arg;
- X{
- X int i;
- X if( ftype ) {
- X for(i=0; i<FORMTABSIZE; i++ ) {
- X if( !strcmp(formtab[i].name,ftype) ) {
- X format = i;
- X (*formtab[format].e_open)(file,ftype,arg);
- X return;
- X }
- X }
- X fprintf(stderr, "warning: no format \"%s\", using \"%s\"\n",
- X ftype, formtab[0].name);
- X }
- X /*
- X * 0th entry is the default format type
- X */
- X format = 0;
- X (*formtab[format].e_open)(file,ftype,arg);
- X}
- X
- Xemitclose()
- X{
- X (*formtab[format].e_close)();
- X}
- X
- Xemitaddr(a)
- Xunsigned long int a;
- X{
- X (*formtab[format].e_addr)(a);
- X}
- X
- Xemitbyte(b)
- Xint b;
- X{
- X (*formtab[format].e_byte)(b);
- X}
- X
- X/* ----------------------------------------------------------------------
- X * Individual file format routines appear here:
- X * Each file format must define the following routines:
- X * open() - Called ONCE before any of the others.
- X * It is passed with a filename and a format
- X * specific argument.
- X *
- X * close() - Called ONCE when no more emit_byte()
- X * function calls will be made.
- X *
- X * addr() - Called when ever a new address has been set
- X * in the assembler (ie. .org, .skip).
- X * This routine is also called once when the
- X * location counter is set to 0 at the very start of
- X * assembling.
- X *
- X * byte() - Called with each byte to be outputed.
- X *
- X */
- X
- X/* ----------------------------------------------------------------------
- X * "tdr" format. For tdr's 68008 system. Generates a
- X * script file readable by a debugger.
- X * [addr] : [byte] [byte] ..
- X *
- X * arg: This is a number in decimal which specifies
- X * the offset, -Ftdr -A0000
- X *
- X * These options specifies the tdr format, with an argument
- X * of 0. This becomes the offset used in generating the
- X * script file. The default if no A is present is 0x10000.
- X *
- X */
- X
- Xstatic unsigned long addr;
- Xstatic FILE *fout;
- Xstatic long int offset;
- Xstatic int newaddr;
- Xstatic int pos=-666;
- X
- Xstatic open1(file,ftype,arg)
- Xchar *file, *ftype, *arg;
- X{
- X fout = fopen(file,"w");
- X if( fout == NULL ) {
- X fprintf(stderr,"Cannot open %s for writting.\n",file);
- X exit(1);
- X }
- X if( arg ) {
- X offset = atoi(arg);
- X } else
- X offset = 0x10000;
- X}
- X
- Xstatic close1()
- X{
- X if( pos != 15 ) fprintf(fout,"\n");
- X fclose(fout);
- X}
- X
- Xstatic addr1(a)
- Xunsigned long int a;
- X{
- X addr = a;
- X newaddr = 1;
- X}
- X
- Xstatic byte1(b)
- Xunsigned char b;
- X{
- X if( newaddr ) {
- X if( pos != -666 ) fprintf(fout,"\n");
- X newaddr = 0;
- X pos = 15;
- X fprintf(fout,"%06x: ",addr+offset);
- X } else if( pos == 15 ) {
- X fprintf(fout,"%06x: ",addr+offset);
- X }
- X
- X fprintf(fout,"%02x ", b&0xff );
- X
- X if( pos-- == 0 ) {
- X fprintf(fout,"\n");
- X pos = 15;
- X }
- X addr += 1;
- X}
- X
- X
- X/* ----------------------------------------------------------------------
- X * "byte" format.
- X * Like "tdr" but each byte is on a line by itself.
- X * This is nice for debugging. No -A is used.
- X */
- X
- Xstatic open2(file,ftype,arg)
- Xchar *file, *ftype, *arg;
- X{
- X fout = fopen(file,"w");
- X if( fout == NULL ) {
- X fprintf(stderr,"Cannot open %s for writting.\n",file);
- X exit(1);
- X }
- X}
- X
- Xstatic close2()
- X{
- X fclose(fout);
- X}
- X
- Xstatic addr2(a)
- Xunsigned long int a;
- X{
- X addr = a;
- X}
- X
- Xstatic byte2(b)
- Xunsigned char b;
- X{
- X fprintf(fout,"%04x: %02x\n", addr, b&0xff );
- X addr += 1;
- X}
- X
- X
- X/* ----------------------------------------------------------------------
- X * "od", this format shows 16 bytes per line, with address.
- X * It also includes ascii on one side.
- X *
- X * The format is similar to the od(1) program under Unix.
- X *
- X */
- X
- Xstatic int pos3;
- Xstatic unsigned char buf[16];
- Xstatic unsigned long saveaddr;
- X
- Xstatic open3(file,ftype,arg)
- Xchar *file, *arg;
- X{
- X fout = fopen(file,"w");
- X if( fout == NULL ) {
- X fprintf(stderr,"Cannot open %s for writting.\n",file);
- X exit(1);
- X }
- X}
- X
- Xstatic close3()
- X{
- X dumpline(saveaddr,buf,pos3-1);
- X fclose(fout);
- X}
- X
- Xstatic addr3(a)
- Xunsigned long int a;
- X{
- X newaddr = 1;
- X addr = a;
- X}
- X
- Xstatic byte3(b)
- Xunsigned char b;
- X{
- X if( newaddr ) {
- X dumpline(saveaddr,buf,pos3-1);
- X pos3 = 0;
- X newaddr = 0;
- X saveaddr = addr;
- X } else if( pos3 == 16 ) {
- X dumpline(saveaddr,buf,pos3-1);
- X pos3 = 0;
- X saveaddr = addr;
- X }
- X buf[pos3++] = b & 0x00ff;
- X
- X addr += 1;
- X}
- X
- Xdumpline(a,b,len)
- Xunsigned long a;
- Xunsigned char *b;
- Xint len;
- X{
- X int i;
- X
- X if(len <= 0 ) return;
- X
- X fprintf(fout,"%04x: ",a);
- X
- X for(i=0; i<8; i++ ) {
- X if( i <= len )
- X fprintf(fout,"%02x ",b[i]);
- X else
- X fprintf(fout," ");
- X }
- X
- X fprintf(fout,"- ");
- X
- X for(i=8; i<16; i++ ) {
- X if( i <= len )
- X fprintf(fout,"%02x ",b[i]);
- X else
- X fprintf(fout," ");
- X }
- X fprintf(fout," ");
- X
- X for(i=0; i<16; i++ ) {
- X if( i <= len )
- X fprintf(fout,"%c",
- X (b[i]>=' ' && b[i]<='~') ? b[i] : '.' );
- X else
- X break;
- X }
- X fprintf(fout,"\n");
- X}
- X
- X/* ----------------------------------------------------------------------
- X * srecord format. This is called with "-Fsrec2", "-Fsrec3", or
- X * "-Fsrec4"...
- X *
- X * arg: This is a number in decimal which specifies
- X * the offset, -Fsrec3 -A0000
- X *
- X * These options specifies the tdr format, with an argument
- X * of 0. This becomes the offset used in generating the
- X * script file. The default if no A is present is 0x0000.
- X *
- X */
- X#define SREC_BYTESPERLINE 32
- X
- Xstatic char format4;
- Xstatic int check4, index4;
- Xstatic char buf4[SREC_BYTESPERLINE];
- Xstatic long address4;
- X
- Xstatic open4(file,ftype,arg)
- Xchar *file, *ftype, *arg;
- X{
- X format4 = ftype[4]; /* will be '2' -- '4' */
- X
- X fout = fopen(file,"w");
- X if( fout == NULL ) {
- X fprintf(stderr,"Cannot open %s for writing.\n",file);
- X exit(1);
- X }
- X
- X if(arg) offset = atoi(arg);
- X else offset = 0;
- X
- X fprintf(fout, "S0030000%02X\n", (~3 & 0xff) );
- X
- X}
- X
- Xstatic close4()
- X{
- X if(index4)
- X finishline();
- X switch(format4) {
- X case '2':
- X fprintf(fout, "S9030000%02X\n", ~3 & 0xff);
- X break;
- X case '3':
- X fprintf(fout, "S804000000%02X\n", ~4 & 0xff);
- X break;
- X case '4':
- X fprintf(fout, "S70500000000%02X\n", ~5 & 0xff);
- X break;
- X }
- X fclose(fout);
- X}
- X
- X
- Xstatic addr4(a)
- Xunsigned long int a;
- X{
- X if(index4>0)
- X finishline();
- X address4 = a + offset;
- X}
- X
- Xstatic byte4(b)
- X{
- X buf4[index4++] = b;
- X if(index4==SREC_BYTESPERLINE) {
- X finishline();
- X address4 += SREC_BYTESPERLINE;
- X }
- X}
- X
- Xfinishline()
- X{
- X int i;
- X
- X check4 = index4 + (address4 & 0xff) + ((address4>>8) & 0xff) + 4;
- X
- X switch(format4) {
- X case '2':
- X fprintf(fout, "S1%02X%04X", index4 + 4, address4 & 0xffff);
- X break;
- X case '3':
- X fprintf(fout, "S2%02X%06X", index4 + 6, address4 & 0xffffff);
- X check4 += ((address4>>16) & 0xff) + 2;
- X break;
- X case '4':
- X fprintf(fout, "S3%02X%08X", index4 + 8, address4);
- X check4 += ((address4>>16) & 0xff) +((address4>>24) & 0xff) + 4;
- X break;
- X }
- X
- X for(i=0; i<index4; i++) {
- X fprintf(fout, "%02X", buf4[i] & 0xff);
- X check4 += buf4[i];
- X }
- X
- X fprintf(fout, "%02X\n", (~check4 & 0xff) );
- X index4 = 0;
- X}
- X
- END_OF_FILE
- if test 8382 -ne `wc -c <'emitter.c'`; then
- echo shar: \"'emitter.c'\" unpacked with wrong size!
- fi
- # end of 'emitter.c'
- fi
- if test -f 'lexer.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lexer.c'\"
- else
- echo shar: Extracting \"'lexer.c'\" \(6816 characters\)
- sed "s/^X//" >'lexer.c' <<'END_OF_FILE'
- X/* ----------------------------------------------------------------------
- X * FILE: lexer.c
- X * PACKAGE: as31 - 8031/8051 Assembler.
- X *
- X * DESCRIPTION:
- X * This file contains the lexical tokenizer for the assembler.
- X * Since yacc is being used the lexer is called yylex().
- X *
- X * In order to produce a listing, some record of the users
- X * source line must be kept. This is done by adding
- X * get_ch(), and unget_ch() routine which returns/ungets a character
- X * but also places information into a secret array.
- X *
- X * When a newline is encountered the text line is returned as
- X * an attribute on the '\n' character.
- X *
- X * REVISION HISTORY:
- X * Jan. 19, 1990 - Created. (Ken Stauffer)
- X *
- X * AUTHOR:
- X * All code in this file written by Ken Stauffer (University of Calgary).
- X * January, 1990.
- X *
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "as31.h"
- X
- Xextern union ystack yylval;
- Xextern int pass;
- X
- Xstruct symbol *looksym();
- Xstruct opcode *lookop();
- Xchar *malloc();
- Xint lineno;
- X
- Xstatic char line[100],*lineptr=line;
- X
- X/* ----------------------------------------------------------------------
- X * get_ch:
- X * Get a character from stdin, place char in line[]
- X */
- X
- Xget_ch()
- X{
- X register int c;
- X
- X c = getchar();
- X if( c != EOF && lineptr - line < sizeof(line) )
- X *lineptr++ = c;
- X return(c);
- X}
- X
- X/* ----------------------------------------------------------------------
- X * unget_ch:
- X * Unget a character and move lineptr back by one.
- X */
- X
- Xunget_ch(c)
- Xint c;
- X{
- X ungetc(c,stdin);
- X if( lineptr > line )
- X lineptr--;
- X}
- X
- X/* ----------------------------------------------------------------------
- X * yylex:
- X * The tokens themselves are returned via return(token)
- X *
- X * Some tokens have attributes. These attributes are returned
- X * by setting a global variable yylval:
- X *
- X * yylval.value
- X * numbers (any base)
- X * strings (in pass 1).
- X * bit positions .0, .1, .2, ...
- X *
- X * yylval.str
- X * strings (in pass 2).
- X * '\n' (both passes).
- X *
- X * yylval.sym
- X * User defined symbols.
- X *
- X * yylval.op
- X * Reserved keyword (opcode/directive/misc.)
- X *
- X * No other fields in yylval are used by yylex().
- X *
- X * Characters that do not have an attribute do
- X * not set anything in the yylval variable.
- X *
- X */
- X
- Xyylex()
- X{
- X static nl_flag=0; /* sync. error messages and the cur. line */
- X register int c;
- X char buf[120]; /* temporary buffer */
- X char *p; /* general pointer */
- X struct symbol *sym;
- X struct opcode *op;
- X
- X int octal=0,hex=0,decimal=0,binary=0;
- X register long value = 0;
- X
- X if( nl_flag ) {
- X nl_flag = 0;
- X lineno++;
- X }
- X
- Xfor(;;) {
- X c = get_ch();
- X switch(c) {
- X case EOF: return(EOF);
- X case ' ':
- X case '\t':
- X break;
- X
- X case '\n':
- X nl_flag = 1;
- X yylval.str = line;
- X *lineptr = '\0';
- X lineptr = line;
- X return('\n');
- X
- X case ';':
- X while((c=get_ch()) != EOF && c!='\n');
- X nl_flag= 1;
- X yylval.str = line;
- X *lineptr = '\0';
- X lineptr = line;
- X return(c);
- X
- X case '"':
- X p = buf;
- X while((c=get_ch()) != EOF && c!='"' && c!='\n') {
- X if( c == '\\' ) {
- X switch(c=get_ch()) {
- X case 'n': c = '\n'; break;
- X case 'r': c = '\r'; break;
- X case 't': c = '\t'; break;
- X case 'b': c = '\b'; break;
- X case '"': c = '"'; break;
- X case '\\': c = '\\'; break;
- X default:
- X error("Invalid escape character: \\%c",c);
- X break;
- X }
- X }
- X if( p-buf<sizeof(buf)-1 )
- X *p++ = c;
- X else {
- X error("String constant longer than %d bytes",
- X sizeof(buf));
- X }
- X }
- X *p = '\0';
- X if( c == '\n' || c == EOF ) {
- X error("String terminated improperly.");
- X unget_ch(c);
- X }
- X
- X if(pass1)
- X yylval.value = strlen(buf);
- X else {
- X if( (p = malloc(strlen(buf)+1)) == NULL )
- X error("Cannot allocate %d bytes",strlen(buf)+1);
- X strcpy(p,buf);
- X yylval.str = p;
- X }
- X return(STRING);
- X
- X case '.':
- X if( (c=get_ch())>='0' && c<='7' ) {
- X yylval.value = c-'0';
- X return(BITPOS);
- X }
- X unget_ch(c);
- X return('.');
- X
- X case '\'':
- X c = get_ch();
- X if( c=='\\' ) {
- X switch(c=get_ch()) {
- X case 'n': c = '\n'; break;
- X case 'r': c = '\r'; break;
- X case 't': c = '\t'; break;
- X case 'b': c = '\b'; break;
- X case '\\': c = '\\'; break;
- X case '\'': c = '\''; break;
- X default:
- X error("Invalid escape character: \\%c",c);
- X }
- X }
- X if( get_ch() != '\'' )
- X error("Missing quote in character constant");
- X yylval.value = c;
- X return(VALUE);
- X
- X case '0': /* parse a number */
- X case '1': /* could be followed by a: */
- X case '2': /* 'b','B' - Binary */
- X case '3': /* 'h','H' - Hex */
- X case '4': /* 'd','D' - Decimal */
- X case '5': /* 'o','O' - Octal */
- X case '6': /* *** Numbers must start with a digit */
- X case '7': /* Numbers could be also preceeded by: */
- X case '8': /* 0x - Hex, 0b - binary */
- X case '9': /* 0 - Octal */
- X
- X p = buf;
- X do {
- X if( p-buf<sizeof(buf)-1 )
- X *p++ = c;
- X c = get_ch();
- X } while( c=='H' || c=='h' || c=='O' || c=='o' ||
- X c=='x' || c=='X' || isxdigit(c) );
- X unget_ch(c);
- X *p = '\0';
- X
- X
- X /* Check any preceeding chars */
- X if( buf[0]=='0' && (buf[1]=='x' || buf[1]=='X') ) {
- X hex++;
- X buf[1] = '0';
- X } else if( buf[0]=='0' &&
- X (buf[1]=='b' || buf[1]=='B') ) {
- X binary++;
- X buf[1] = '0';
- X }
- X else if( buf[0]=='0' ) octal++;
- X
- X /* check any trailing chars */
- X c = *(p-1);
- X if( !hex && (c=='b' || c=='B') )
- X { binary++; *(p-1) = '\0'; }
- X else if( c=='H' || c=='h' )
- X { hex++; *(p-1) = '\0'; }
- X else if( !hex && (c=='D' || c=='d') )
- X { decimal++; *(p-1) = '\0'; }
- X else if( c=='O' || c=='o' )
- X { octal++; *(p-1) = '\0'; }
- X else if( !hex && !octal && !binary) decimal++;
- X
- X if( binary ) {
- X for(p=buf; *p; p++ ) {
- X if( *p=='1' ) value = value<<1 + 1;
- X else if( *p=='0' ) value = value<<1;
- X else
- X error("Invalid binary digit: %c",*p);
- X }
- X yylval.value = value;
- X return(VALUE);
- X }
- X
- X if( hex ) {
- X for(p=buf; *p; p++ ) {
- X value <<= 4;
- X if( isdigit(*p) )
- X value += *p-'0';
- X else if( *p>='a' && *p<='f' )
- X value += *p-'a'+ 10;
- X else if( *p>='A' && *p<='F' )
- X value += *p-'A'+ 10;
- X else
- X error("Invalid hex digit: %c",*p);
- X }
- X yylval.value = value;
- X return(VALUE);
- X }
- X
- X if( decimal ) {
- X for(p=buf; *p; p++ ) {
- X if( isdigit(*p) )
- X value = value*10 + *p-'0';
- X else
- X error("Invalid decimal digit: %c",*p);
- X }
- X yylval.value = value;
- X return(VALUE);
- X }
- X
- X if( octal ) {
- X for(p=buf; *p; p++ ) {
- X if( *p>='0' && *p<='7' )
- X value = value<<3 + *p-'0';
- X else
- X error("Invalid octal digit: %c",*p);
- X }
- X yylval.value = value;
- X return(VALUE);
- X }
- X
- X default:
- X if( isalpha(c) || c=='_' ) {
- X p = buf;
- X do {
- X if( p-buf<sizeof(buf)-1 )
- X *p++ = c;
- X c = get_ch();
- X } while( isalnum(c) || c=='_' );
- X *p = '\0';
- X unget_ch(c);
- X if( op = lookop(buf) ) {
- X yylval.op = op;
- X return(op->type);
- X }
- X sym = looksym(buf);
- X yylval.sym = sym;
- X return(SYMBOL);
- X } else
- X return(c);
- X } /* switch */
- X} /* for */
- X
- X} /* yylex */
- END_OF_FILE
- if test 6816 -ne `wc -c <'lexer.c'`; then
- echo shar: \"'lexer.c'\" unpacked with wrong size!
- fi
- # end of 'lexer.c'
- fi
- if test -f 'main.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'main.c'\"
- else
- echo shar: Extracting \"'main.c'\" \(2745 characters\)
- sed "s/^X//" >'main.c' <<'END_OF_FILE'
- X/* ----------------------------------------------------------------------
- X * FILE: main.c
- X * PACKAGE: as31 - 8031/8051 Assembler.
- X *
- X * DESCRIPTION:
- X * The file contains main(). It handles the arguments and makes
- X * sure that pass 1 is done before pass 2 etc...
- X *
- X * REVISION HISTORY:
- X * Jan. 19, 1990 - Created. (Ken Stauffer)
- X *
- X * AUTHOR:
- X * All code in this file written by Ken Stauffer (University of Calgary).
- X * January, 1990. */ static char
- X * id_id= "Written by: Ken Stauffer";/*
- X *
- X */
- X
- X#include <stdio.h>
- X#include <setjmp.h>
- X
- Xextern int lineno;
- Xextern int pass,fatal;
- Xextern unsigned long lc;
- X
- Xjmp_buf main_env;
- Xchar *asmfile;
- Xint dashl=0;
- XFILE *listing;
- X
- X/* ----------------------------------------------------------------------
- X * checkext:
- X * Check the string s, for the presence of an extenstion e.
- X * Return the position of the start of e in s.
- X * or return NULL.
- X */
- X
- Xchar *checkext(s,e)
- Xchar *s,*e;
- X{
- X register char *ps = s, *pe = e;
- X
- X while( *ps ) ps++;
- X while( *pe ) pe++;
- X
- X for( ; ps>=s && pe>=e && *ps == *pe; ps--, pe-- )
- X if( pe == e ) return(ps);
- X return(NULL);
- X}
- X
- Xmain(argc,argv)
- Xchar *argv[];
- X{
- X FILE *fin;
- X char *p,*dashF=NULL, *dashA=NULL;
- X char objfile[100];
- X char lstfile[100];
- X int i;
- X
- X if( argc < 2 ) {
- X fprintf(stderr,"Usage: %s [-l] [-Ffmt] [-Aarg] infile.asm\n",
- X argv[0]);
- X emitusage();
- X exit(1);
- X }
- X
- X for(i=1; i<argc; i++ ) {
- X if( argv[i][0] != '-' ) break;
- X if( argv[i][1] == 'l' ) dashl = 1;
- X else if( dashF == NULL && argv[i][1] == 'F' )
- X dashF = argv[i]+2;
- X else if( dashA == NULL && argv[i][1] == 'A' )
- X dashA = argv[i]+2;
- X else {
- X fprintf(stderr,"Duplicate or unknown flag.\n");
- X exit(1);
- X }
- X }
- X if( i == argc ) {
- X fprintf(stderr,"Missing input file.\n");
- X exit(1);
- X }
- X
- X if( (p=checkext(argv[i],".asm")) == NULL ) {
- X fprintf(stderr,"Input file \"%s\" must end with .asm\n",
- X argv[i]);
- X exit(1);
- X }
- X asmfile = argv[i];
- X
- X if( (fin = freopen(argv[i],"r",stdin)) == NULL ) {
- X fprintf(stderr,"Cannot open input file: %s\n",argv[i]);
- X exit(1);
- X }
- X
- X if( dashl ) {
- X strcpy(lstfile,argv[i]);
- X strcpy(lstfile+(p-argv[i]),".lst");
- X listing = fopen(lstfile,"w");
- X if( listing == NULL ) {
- X fprintf(stderr,"Cannot open file: %s for writting.\n",
- X lstfile);
- X exit(1);
- X }
- X }
- X strcpy(objfile,argv[i]);
- X strcpy(objfile+(p-argv[i]),".obj");
- X
- X emitopen(objfile,dashF,dashA);
- X
- X syminit();
- X fatal = 0;
- X lineno = 1;
- X pass=0;
- X lc = 0x0000;
- X
- X if( setjmp(main_env) ) {
- X fclose(fin);
- X emitclose();
- X unlink(objfile);
- X exit(1);
- X }
- X
- X /*
- X ** P A S S 1
- X */
- X yyparse();
- X if( fatal ) longjmp(main_env,1);
- X
- X rewind(fin);
- X lineno = 1;
- X pass++;
- X lc = 0x0000;
- X emitaddr(lc);
- X
- X /*
- X ** P A S S 2
- X */
- X yyparse();
- X
- X emitclose();
- X fclose(fin);
- X if( dashl )
- X fclose(listing);
- X exit(0);
- X
- X}
- END_OF_FILE
- if test 2745 -ne `wc -c <'main.c'`; then
- echo shar: \"'main.c'\" unpacked with wrong size!
- fi
- # end of 'main.c'
- fi
- if test -f 'makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'makefile'\"
- else
- echo shar: Extracting \"'makefile'\" \(856 characters\)
- sed "s/^X//" >'makefile' <<'END_OF_FILE'
- X# FILE: makefile
- X# PACKAGE: as31 - 8031/8051 Assembler.
- X#
- X# DESCRIPTION:
- X#
- X#
- X# REVISION HISTORY:
- X# Jan. 19, 1990 - Created. (Ken Stauffer).
- X# Jan. 30, 1990 - Theo played here.
- X
- XCFLAGS=-O
- XYACCFLAGS=-d
- XOBJ=as31.o symbol.o lexer.o emitter.o main.o
- XSHARFILES=README as31.h as31.y as31.man emitter.c lexer.c main.c makefile \
- X symbol.c new.asm
- X
- Xas31: $(OBJ)
- X $(CC) $(CFLAGS) -o as31 $(OBJ)
- X chmod a+rx as31
- X
- Xmain.o: main.c as31.h
- Xemitter.o: emitter.c as31.h
- Xsymbol.o: symbol.c as31.h
- Xlexer.o: lexer.c as31.h
- Xas31.o: as31.c
- Xas31.c: as31.y as31.h
- X yacc $(YACCFLAGS) as31.y
- X /bin/mv y.tab.c as31.c
- X
- Xman: as31.cat
- X
- Xas31.cat: as31.man
- X nroff -man as31.man > as31.cat
- X chmod a+r as31.cat as31.man
- X
- Xasm: new.obj ram.obj
- X
- Xnew.obj: new.asm
- X ./as31 -Ftdr -l new.asm
- X
- Xclean:
- X $(RM) *~ *.o as31.c y.tab.h as31.shar
- X
- Xshar:
- X shar $(SHARFILES) > as31.shar
- END_OF_FILE
- if test 856 -ne `wc -c <'makefile'`; then
- echo shar: \"'makefile'\" unpacked with wrong size!
- fi
- # end of 'makefile'
- fi
- if test -f 'symbol.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'symbol.c'\"
- else
- echo shar: Extracting \"'symbol.c'\" \(10609 characters\)
- sed "s/^X//" >'symbol.c' <<'END_OF_FILE'
- X/* ----------------------------------------------------------------------
- X * FILE: symbol.c
- X * PACKAGE: as31 - 8031/8051 Assembler.
- X *
- X * DESCRIPTION:
- X * This file contains the symbol table search/insertion routines
- X * associated with user defined symbols.
- X *
- X * The reserved keyword (instructions/directives) look up routine
- X * is defined here.
- X *
- X * The opcode table for all of the instructions is located in this
- X * file.
- X *
- X * REVISION HISTORY:
- X * Jan. 19, 1990 - Created. (Ken Stauffer)
- X *
- X * AUTHOR:
- X * All code in this file written by Ken Stauffer (University of Calgary)
- X * January, 1990.
- X *
- X */
- X
- X#include "as31.h"
- X#define NULL (0)
- X
- X#define B(a) (0xF0+(a))
- X#define ACC(a) (0xE0+(a))
- X#define PSW(a) (0xD0+(a))
- X#define T2CON(a) (0xC8+(a))
- X#define IP(a) (0xB8+(a))
- X#define P3(a) (0xB0+(a))
- X#define IE(a) (0xA8+(a))
- X#define P2(a) (0xA0+(a))
- X#define SCON(a) (0x98+(a))
- X#define P1(a) (0x90+(a))
- X#define TCON(a) (0x88+(a))
- X#define P0(a) (0x80+(a))
- X
- X/* ----------------------------------------------------------------------
- X * sinit[]
- X * These symbols are not reserved keywords.
- X * This array contains the initial symbol table entries
- X * for the user symbol table. The symbols are
- X * basically convienient names that make writting
- X * in 8031/8051 bearable.
- X *
- X * The function syminit() inserts these entries into the
- X * symbol table.
- X *
- X */
- X
- Xstatic struct symbol sinit[] = {
- X { "AC", LABEL, PSW(6), NULL },
- X { "ACC", LABEL, ACC(0), NULL },
- X { "B", LABEL, B(0), NULL },
- X { "CY", LABEL, PSW(7), NULL },
- X { "DPH", LABEL, 0x83, NULL },
- X { "DPL", LABEL, 0x82, NULL },
- X { "EA", LABEL, IE(7), NULL },
- X { "ES", LABEL, IE(4), NULL },
- X { "ET0", LABEL, IE(1), NULL },
- X { "ET1", LABEL, IE(3), NULL },
- X { "ET2", LABEL, IE(5), NULL },
- X { "EX0", LABEL, IE(0), NULL },
- X { "EX1", LABEL, IE(2), NULL },
- X { "EXEN2", LABEL, T2CON(3),NULL },
- X { "EXF2", LABEL, T2CON(6),NULL },
- X { "F0", LABEL, PSW(5), NULL },
- X { "IE", LABEL, IE(0), NULL },
- X { "IE0", LABEL, TCON(1),NULL },
- X { "IE1", LABEL, TCON(3),NULL },
- X { "IP", LABEL, IP(0), NULL },
- X { "IT0", LABEL, TCON(0),NULL },
- X { "IT1", LABEL, TCON(2),NULL },
- X { "OV", LABEL, PSW(2), NULL },
- X { "P", LABEL, PSW(0), NULL },
- X { "P0", LABEL, P0(0), NULL },
- X { "P1", LABEL, P1(0), NULL },
- X { "P2", LABEL, P2(0), NULL },
- X { "P3", LABEL, P3(0), NULL },
- X { "PCON", LABEL, 0x87, NULL },
- X { "PS", LABEL, IP(4), NULL },
- X { "PSW", LABEL, PSW(0), NULL },
- X { "PT0", LABEL, IP(1), NULL },
- X { "PT1", LABEL, IP(3), NULL },
- X { "PT2", LABEL, IP(5), NULL },
- X { "PX0", LABEL, IP(0), NULL },
- X { "PX1", LABEL, IP(2), NULL },
- X { "RB8", LABEL, SCON(2),NULL },
- X { "RCAP2H", LABEL, 0xCB, NULL },
- X { "RCAP2L", LABEL, 0xCA, NULL },
- X { "RCLK", LABEL, T2CON(5),NULL },
- X { "REN", LABEL, SCON(4),NULL },
- X { "RI", LABEL, SCON(0),NULL },
- X { "RL2", LABEL, T2CON(0),NULL },
- X { "RS0", LABEL, PSW(3), NULL },
- X { "RS1", LABEL, PSW(4), NULL },
- X { "SBUF", LABEL, 0x99, NULL },
- X { "SCON", LABEL, SCON(0),NULL },
- X { "SM0", LABEL, SCON(7),NULL },
- X { "SM1", LABEL, SCON(6),NULL },
- X { "SM2", LABEL, SCON(5),NULL },
- X { "SP", LABEL, 0x81, NULL },
- X { "T2CON", LABEL, T2CON(0),NULL },
- X { "TB8", LABEL, SCON(3),NULL },
- X { "TCLK", LABEL, T2CON(4),NULL },
- X { "TCON", LABEL, TCON(0),NULL },
- X { "TF0", LABEL, TCON(5),NULL },
- X { "TF1", LABEL, TCON(7),NULL },
- X { "TF2", LABEL, T2CON(7),NULL },
- X { "TH0", LABEL, 0x8C, NULL },
- X { "TH1", LABEL, 0x8D, NULL },
- X { "TH2", LABEL, 0xCD, NULL },
- X { "TI", LABEL, SCON(1),NULL },
- X { "TL0", LABEL, 0x8A, NULL },
- X { "TL1", LABEL, 0x8B, NULL },
- X { "TL2", LABEL, 0xCC, NULL },
- X { "TMOD", LABEL, 0x89, NULL },
- X { "TR0", LABEL, TCON(4),NULL },
- X { "TR1", LABEL, TCON(6),NULL },
- X { "TR2", LABEL, T2CON(2),NULL }
- X};
- X
- X#define SINITSIZE (sizeof(sinit)/sizeof(sinit[0]))
- X
- X/* ----------------------------------------------------------------------
- X * opcode vectors:
- X * These arrays contain the various opcodes for the
- X * various forms an instruction may take.
- X *
- X * The ordering of these opcodes is very critical to the
- X * proper fuctioning of the assembler.
- X *
- X * When a given form of an instruction is parsed, the parser
- X * indexes one of these arrays by the correct amount and thus
- X * obtains the correct opcode for the particular form.
- X *
- X */
- X
- Xstatic unsigned char acall[]= { 0x11 };
- Xstatic unsigned char add[]= { 0x28, 0x25, 0x26, 0x24 };
- Xstatic unsigned char addc[]= { 0x38, 0x35, 0x36, 0x34 };
- Xstatic unsigned char ajmp[]= { 0x01 };
- Xstatic unsigned char anl[]= { 0x58, 0x55, 0x56, 0x54, 0x52, 0x53, 0x82,
- X 0xb0 };
- Xstatic unsigned char cjne[]= { 0xb5, 0xb4, 0xb8, 0xb6 };
- Xstatic unsigned char clr[]= { 0xe4, 0xc3, 0xc2 };
- Xstatic unsigned char cpl[]= { 0xf4, 0xb3, 0xb2 };
- Xstatic unsigned char da[]= { 0xd4 };
- Xstatic unsigned char dec[]= { 0x14, 0x18, 0x15, 0x16 };
- Xstatic unsigned char div[]= { 0x84 };
- Xstatic unsigned char djnz[]= { 0xd8, 0xd5 };
- Xstatic unsigned char inc[]= { 0x04, 0x08, 0x05, 0x06, 0xa3 };
- Xstatic unsigned char jb[]= { 0x20 };
- Xstatic unsigned char jbc[]= { 0x10 };
- Xstatic unsigned char jc[]= { 0x40 };
- Xstatic unsigned char jmp[]= { 0x73 };
- Xstatic unsigned char jnb[]= { 0x30 };
- Xstatic unsigned char jnc[]= { 0x50 };
- Xstatic unsigned char jnz[]= { 0x70 };
- Xstatic unsigned char jz[]= { 0x60 };
- Xstatic unsigned char lcall[]= { 0x12 };
- Xstatic unsigned char ljmp[]= { 0x02 };
- Xstatic unsigned char mov[]= { 0xe8, 0xe5, 0xe6, 0x74, 0xf5, 0x75, 0xf8,
- X 0xa8, 0x78, 0x88, 0x85, 0x86, 0xf6, 0xa6,
- X 0x76, 0x90, 0xa2, 0x92 };
- Xstatic unsigned char movc[]= { 0x93, 0x83 };
- Xstatic unsigned char movx[]= { 0xe2, 0xe3, 0xe0, 0xf2, 0xf3, 0xf0 };
- Xstatic unsigned char mul[]= { 0xa4 };
- Xstatic unsigned char nop[]= { 0x00 };
- Xstatic unsigned char orl[]= { 0x48, 0x45, 0x46, 0x44, 0x42, 0x43, 0x72,
- X 0xa0 };
- Xstatic unsigned char pop[]= { 0xd0 };
- Xstatic unsigned char push[]= { 0xc0 };
- Xstatic unsigned char ret[]= { 0x22 };
- Xstatic unsigned char reti[]= { 0x32 };
- Xstatic unsigned char rl[]= { 0x23 };
- Xstatic unsigned char rlc[]= { 0x33 };
- Xstatic unsigned char rr[]= { 0x03 };
- Xstatic unsigned char rrc[]= { 0x13 };
- Xstatic unsigned char setb[]= { 0xd3, 0xd2 };
- Xstatic unsigned char sjmp[]= { 0x80 };
- Xstatic unsigned char subb[]= { 0x98, 0x95, 0x96, 0x94 };
- Xstatic unsigned char swap[]= { 0xc4 };
- Xstatic unsigned char xch[]= { 0xc8, 0xc5, 0xc6 };
- Xstatic unsigned char xchd[]= { 0xd6 };
- Xstatic unsigned char xrl[]= { 0x68, 0x65, 0x66, 0x64, 0x62, 0x63 };
- X
- X/* ----------------------------------------------------------------------
- X * optable[]
- X * This table contains opcodes, directives and a few reserved
- X * symbols.
- X *
- X * The second field is the keywords token value.
- X *
- X * Unless the symbol is an opcode, the third field will
- X * be NULL.
- X *
- X * The third field is a pointer to an array of opcode bytes.
- X *
- X */
- X
- Xstatic struct opcode optable[] = {
- X {"a", A, NULL },
- X {"ab", AB, NULL },
- X {"acall", ACALL, acall },
- X {"add", ADD, add },
- X {"addc", ADDC, addc },
- X {"ajmp", AJMP, ajmp },
- X {"anl", ANL, anl },
- X {"byte", D_BYTE, NULL },
- X {"c", C, NULL },
- X {"cjne", CJNE, cjne },
- X {"clr", CLR, clr },
- X {"cpl", CPL, cpl },
- X {"da", DA, da },
- X {"dec", DEC, dec },
- X {"div", DIV, div },
- X {"djnz", DJNZ, djnz },
- X {"dptr", DPTR, NULL },
- X {"end", D_END, NULL },
- X {"equ", D_EQU, NULL },
- X {"flag", D_FLAG, NULL },
- X {"inc", INC, inc },
- X {"jb", JB, jb },
- X {"jbc", JBC, jbc },
- X {"jc", JC, jc },
- X {"jmp", JMP, jmp },
- X {"jnb", JNB, jnb },
- X {"jnc", JNC, jnc },
- X {"jnz", JNZ, jnz },
- X {"jz", JZ, jz },
- X {"lcall", LCALL, lcall },
- X {"ljmp", LJMP, ljmp },
- X {"mov", MOV, mov },
- X {"movc", MOVC, movc },
- X {"movx", MOVX, movx },
- X {"mul", MUL, mul },
- X {"nop", NOP, nop },
- X {"org", D_ORG, NULL },
- X {"orl", ORL, orl },
- X {"pc", PC, NULL },
- X {"pop", POP, pop },
- X {"push", PUSH, push },
- X {"r0", R0, NULL },
- X {"r1", R1, NULL },
- X {"r2", R2, NULL },
- X {"r3", R3, NULL },
- X {"r4", R4, NULL },
- X {"r5", R5, NULL },
- X {"r6", R6, NULL },
- X {"r7", R7, NULL },
- X {"ret", RET, ret },
- X {"reti", RETI, reti },
- X {"rl", RL, rl },
- X {"rlc", RLC, rlc },
- X {"rr", RR, rr },
- X {"rrc", RRC, rrc },
- X {"setb", SETB, setb },
- X {"sjmp", SJMP, sjmp },
- X {"skip", D_SKIP, NULL },
- X {"subb", SUBB, subb },
- X {"swap", SWAP, swap },
- X {"word", D_WORD, NULL },
- X {"xch", XCH, xch },
- X {"xchd", XCHD, xchd },
- X {"xrl", XRL, xrl }
- X};
- X
- X#define OPTABSIZE (sizeof(optable)/sizeof(struct opcode))
- X
- X/* ----------------------------------------------------------------------
- X * strcase:
- X * A case IN-sensitive string compare.
- X *
- X */
- X
- Xstrcase(s,t)
- Xchar *s,*t;
- X{
- X for( ; (*s|040) == (*t|040); s++, t++)
- X if( *s == '\0') return(0);
- X return( (*s|040) - (*t|040) );
- X}
- X
- X/* ----------------------------------------------------------------------
- X * lookop:
- X * Do a binary search through optable[], for a matching
- X * symbol. Return the symbol found or NULL.
- X *
- X */
- X
- Xstruct opcode *lookop(s)
- Xchar *s;
- X{
- X register int low,high,mid,cond;
- X
- X low = 0;
- X high = OPTABSIZE-1;
- X while( low<=high ) {
- X mid = (low+high)/2;
- X if( (cond = strcase(s,optable[mid].name)) < 0 )
- X high = mid-1;
- X else if(cond > 0 )
- X low = mid+1;
- X else
- X return(&optable[mid]);
- X }
- X return(NULL);
- X}
- X
- X/* ----------------------------------------------------------------------
- X * symtab, hash, looksym:
- X * User symbol table routines.
- X * symtab is the hash table for the user symbols.
- X * (chaining is used for collision resolution).
- X *
- X */
- X
- Xstatic struct symbol *symtab[HASHTABSIZE];
- X
- Xstatic hash(s)
- Xchar *s;
- X{
- X register char *p;
- X register unsigned h=0,g;
- X for(p=s; *p; p++) {
- X h = (h<<4) + *p;
- X if( g = h&0xf0000000 ) {
- X h = h ^ (g >> 24);
- X h = h ^ g;
- X }
- X }
- X return( h % HASHTABSIZE );
- X}
- X
- Xstruct symbol *looksym(s)
- Xchar *s;
- X{
- X register struct symbol *ptr,*prev;
- X char *malloc(),*p;
- X register int hv;
- X
- X hv = hash(s);
- X
- X prev = NULL;
- X for(ptr=symtab[hv]; ptr; ptr = ptr->next) {
- X if( !strcmp(ptr->name,s) ) {
- X if( prev != NULL ) {
- X prev->next = ptr->next;
- X ptr->next = symtab[hv];
- X symtab[hv] = ptr;
- X }
- X return(ptr);
- X }
- X prev = ptr;
- X }
- X
- X if( p = malloc(strlen(s)+1) )
- X strcpy(p,s);
- X else
- X error("Cannot allocate %d bytes",strlen(s)+1);
- X
- X ptr = (struct symbol *) malloc( sizeof(struct symbol) );
- X if( ptr == NULL )
- X error("Cannot allocate %d bytes",sizeof(struct symbol));
- X ptr->name = p;
- X ptr->type = UNDEF;
- X ptr->next = symtab[hv];
- X symtab[hv] = ptr;
- X return(ptr);
- X}
- X
- X/* ----------------------------------------------------------------------
- X * syminit:
- X * Initializes the hash table, with the initial symbols from
- X * sinit[]
- X *
- X */
- X
- Xsyminit()
- X{
- X register int i,hv;
- X
- X for(i=0; i<SINITSIZE; i++ ) {
- X hv = hash(sinit[i].name);
- X if( symtab[hv] )
- X sinit[i].next = symtab[hv];
- X symtab[hv] = &sinit[i];
- X }
- X}
- END_OF_FILE
- if test 10609 -ne `wc -c <'symbol.c'`; then
- echo shar: \"'symbol.c'\" unpacked with wrong size!
- fi
- # end of 'symbol.c'
- fi
- if test -f 'new.asm' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'new.asm'\"
- else
- echo shar: Extracting \"'new.asm'\" \(10618 characters\)
- sed "s/^X//" >'new.asm' <<'END_OF_FILE'
- X; -----------------------------------------------------------------------
- X; - debugger v2.0 theo de raadt 21/1/90 -
- X; NOTE: Hardware has to be specially built to handle this monitor.
- X; The CODE address space and the DATA address space have to be mapped
- X; on top of each other. ie. CHIP_READ* = 8031RD* AND 8031PSEN* and
- X; CHIP_WRITE* = 8031WR*.
- X; Within this (combined) address space, you can now use either MOVX
- X; or MOVC for the same effect.
- X; In this address space, I have placed the rom this debugger is in
- X; at 0x0000 and ram at 0x8000. (additional IO would go in between.)
- X; (actually, I used a battery backed up static ram at 0x000.)
- X; Some of the commands in the help are actually unimplimented. It
- X; suited my purposes. The 'g' command could be much improved, to have
- X; a seperate register set for the called routine.
- X; -----------------------------------------------------------------------
- X
- X .org 0
- Xstart: nop ; for accidental overwrite if ram
- X ; at 0 -- bug in my decode logic?
- X mov P3, #0xff ; use alternate fns on P3
- X ajmp main
- X
- X; -----------------------------------------------------------------------
- X; SERINIT() nothing hurt
- Xserinit: mov TMOD, #0x20 ; timer 1 mode 2
- X ; mov TH1, #230 ; 1200 baud
- X mov TH1,#243 ; 4800 baud
- X mov TCON, #0x40 ; turn timer 1 on
- X mov SCON, #0x52 ; serial mode 1 rx, fake tx done
- X
- X mov A, PCON ; for 4800 baud
- X setb ACC.7
- X mov PCON, A
- X ret
- X
- X; -----------------------------------------------------------------------
- X; PUTC( A=char )
- Xputc: jnb TI, putc ; wait for tx free
- X clr TI
- X mov SBUF, A ; send it
- X ret
- X
- X; -----------------------------------------------------------------------
- X; GETC() A=char
- Xgetc: jnb RI, getc
- X clr RI
- X mov A, SBUF
- X ret
- X
- X; -----------------------------------------------------------------------
- X; GETS( DPTR=start of string ) A not hurt, DPTR at start of string
- Xgets: push ACC
- X push DPL
- X push DPH
- X mov A, R3
- X push ACC
- X
- X clr A
- X mov R3, A
- Xgets_nxt: lcall getc
- X cjne A, #8, gets_notbs
- X ajmp gets_bs
- Xgets_notbs: cjne A, #'\r', gets_good
- X clr A
- X movx @DPTR, A
- X
- X pop ACC
- X mov R3, A
- X pop DPH
- X pop DPL
- X pop ACC
- X ret
- X
- Xgets_bs: mov A, R3 ; backspaced too far
- X jz gets_nxt
- X dec A
- X mov R3, A
- X
- X mov A, #8 ; "\b \b"
- X lcall putc
- X mov A, #' '
- X lcall putc
- X mov A, #8
- X lcall putc
- X
- X setb C ; this is "dec DPTR"
- X mov A, DPL
- X subb A, #0
- X mov DPL, A
- X mov A, DPH
- X subb A, #0
- X mov DPH, A
- X ajmp gets_nxt
- X
- Xgets_good: movx @DPTR, A
- X lcall putc
- X inc DPTR
- X inc R3
- X ajmp gets_nxt
- X
- X; ----------------------------------------------------------------------
- X; HEXPARSE( DPTR=string ) A not hurt, DPTR advanced, R0/R1 [H/L] return
- Xhexparse: push ACC
- X
- Xhp_char: movx A, @DPTR ; get char
- X
- X clr C
- X subb A, #'a'
- X jc hp_notalpha ; < 'a' not hex alpha char
- X subb A, #5+1
- X jnc hp_notalpha ; > 'f' not hex aplha char
- X movx A, @DPTR
- X clr C
- X subb A, #'a'-10
- X sjmp hp_nybble
- X
- Xhp_notalpha: movx A, @DPTR
- X clr C
- X subb A, #'0'
- X jc hp_notdigit ; < '0' not hex digit
- X subb A, #9+1
- X jnc hp_notdigit ; > '9' not hex digit
- X movx A, @DPTR
- X clr C
- X subb A, #'0'
- X
- Xhp_nybble: inc DPTR
- X
- X anl A, #0x0f
- X push ACC ; R0 R1
- X mov A, R0 ; HHHH LLLL hhhh llll
- X swap A
- X anl A, #0xf0
- X mov R0, A
- X mov A, R1
- X swap A ; shift left by nybble
- X anl A, #0x0f
- X orl A, R0
- X mov R0, A
- X mov A, R1
- X swap A
- X anl A, #0xf0
- X mov R1, A
- X pop ACC
- X orl A, R1
- X mov R1, A ; LLLL hhhh llll aaaa
- X
- X ; debugging
- X ; push ACC
- X ; push DPL
- X ; push DPH
- X ; mov DPH, R0
- X ; mov DPL, R1
- X ; lcall putword
- X ; lcall putnl
- X ; pop DPH
- X ; pop DPL
- X ; pop ACC
- X
- X sjmp hp_char
- X
- Xhp_notdigit: pop ACC
- X ret
- X
- X; ----------------------------------------------------------------------
- X; EATSPACE( DPTR=string ) A not hurt, DPTR advanced
- Xeatspace: push ACC
- Xeatspace_loop: movx A, @DPTR
- X cjne A, #' ', eatspace_done
- X inc DPTR
- X sjmp eatspace_loop
- Xeatspace_done: pop ACC
- X ret
- X
- X; -----------------------------------------------------------------------
- X; PUTS( DPTR=string ) A not hurt, DPTR at end of string
- Xputs: push ACC
- Xputs_ch: movx A, @DPTR ; get ch
- X jz puts_q ; null - finished str
- X lcall putc
- X inc DPTR
- X sjmp puts_ch ; go for next
- Xputs_q: pop ACC
- X ret
- X
- X; -----------------------------------------------------------------------
- X; PUTNL() nothing hurt
- Xputnl: push ACC
- X mov A, #0x0d
- X lcall putc
- X mov A, #0x0a
- X lcall putc
- X pop ACC
- X ret
- X
- X; -----------------------------------------------------------------------
- X; putword( DPTR=word) nothing hurt
- Xputword: push ACC
- X mov A, DPH
- X lcall putbyte
- X mov A, DPL
- X lcall putbyte
- X pop ACC
- X ret
- X
- X; -----------------------------------------------------------------------
- X; putbyte( A=byte) nothing hurt
- Xputbyte: push ACC
- X push ACC
- X swap A
- X lcall putnyb
- X pop ACC
- X lcall putnyb
- X pop ACC
- X ret
- X
- X; -----------------------------------------------------------------------
- X; putnyb( A=nybble ) A hurt
- Xputnyb: anl A, #0x0f
- X push ACC
- X clr C
- X subb A, #10
- X jc pn_digit ; <= 9, then it's a digit
- X add A, #'a' ; alphabetic
- X lcall putc
- X pop ACC
- X ret
- X
- Xpn_digit: pop ACC ; it's a digit
- X add A, #'0'
- X lcall putc
- X ret
- X
- X; -----------------------------------------------------------------------
- Xmain: lcall serinit
- X mov DPTR, #run_regs_psw ; initialize psw at least!
- X clr A
- X movx @DPTR, A
- X mov DPTR, #title_msg
- X lcall puts
- X
- Xnext_line: mov A, #'>' ; prompt
- X lcall putc
- X
- X mov DPTR, #linebuf ; get cmd
- X lcall gets
- X lcall putnl
- X
- Xnext_cmd: lcall eatspace
- X movx A, @DPTR
- X jz next_line
- X
- X ; --------------------------------------------------
- X cjne A, #'g', cmd_notgo ; g --> lcall addr..
- X push DPL
- X push DPH
- X push ACC
- X push PSW
- X
- X mov DPTR, #go_return ; come back to here..
- X push DPL
- X push DPH
- X
- X mov A, R1 ; return on top of function
- X push ACC
- X mov A, R0
- X push ACC
- X mov DPTR, #run_regs
- X movx A, @DPTR ; DPH
- X push ACC
- X inc DPTR
- X movx A, @DPTR ; DPL
- X push ACC
- X inc DPTR
- X movx A, @DPTR ; PSW
- X push ACC
- X inc DPTR
- X movx A, @DPTR ; ACC
- X pop PSW
- X pop DPL
- X pop DPH
- X ret ; enter it
- X
- Xgo_return: pop PSW
- X pop ACC
- X pop DPH
- X pop DPL
- X inc DPTR
- X sjmp next_cmd
- X
- X ; --------------------------------------------------
- Xcmd_notgo: cjne A, #'R', cmd_notregs
- X inc DPTR
- X push DPH
- X push DPL
- X mov DPTR, #regs_msg ; "DPTR ACC PSW"
- X lcall puts
- X mov DPTR, #run_regs
- X movx A, @DPTR
- X acall putbyte ; xx
- X inc DPTR
- X movx A, @DPTR
- X acall putbyte ; xx
- X mov A, #' '
- X acall putc
- X inc DPTR
- X movx A, @DPTR
- X acall putbyte ; xx
- X inc DPTR
- X mov A, #' '
- X acall putc
- X acall putc
- X movx A, @DPTR
- X acall putbyte ; xx
- X acall putnl
- X pop DPL
- X pop DPH
- X sjmp next_cmd
- X
- X ; --------------------------------------------------
- Xcmd_notregs: cjne A, #':', cmd_notenter ; : --> eat bytes..
- X inc DPTR
- X mov A, R2
- X push ACC
- X mov A, R3
- X push ACC
- X mov A, R0
- X mov R2, A
- X mov A, R1
- X mov R3, A ; R2/R3 = mem ptr
- X
- Xenter_next: lcall eatspace
- X movx A, @DPTR
- X jz enter_done
- X
- X push DPL
- X clr A
- X mov R0, A
- X mov R1, A
- X lcall hexparse
- X pop ACC
- X cjne A, DPL, enter_number
- X sjmp enter_next
- X
- Xenter_number: push DPL
- X push DPH
- X mov DPH, R2 ; put low byte only
- X mov DPL, R3
- X mov A, R1
- X movx @DPTR, A
- X inc DPTR
- X mov R2, DPH
- X mov R3, DPL
- X pop DPH
- X pop DPL
- X sjmp enter_next
- X
- Xenter_done: pop ACC
- X mov R3, A
- X pop ACC
- X mov R2, A
- X ajmp next_cmd
- X
- X ; --------------------------------------------------
- Xcmd_notenter: cjne A, #'?', cmd_nothelp
- X push DPL
- X push DPH
- X mov DPTR, #help_msg
- X lcall puts
- X pop DPH
- X pop DPL
- X inc DPTR
- X ajmp next_cmd
- X
- X ; --------------------------------------------------
- Xcmd_nothelp: cjne A, #'l', cmd_notlist
- X push DPL
- X push DPH
- X push B
- X clr A
- X mov B, ACC
- X mov DPH, R0
- X mov DPL, R1
- X lcall putword ; addr: [16 bytes]
- X mov A, #':'
- X lcall putc
- X mov A, #' '
- X lcall putc
- Xcl_nextbyte: movx A, @DPTR
- X lcall putbyte
- X mov A, #' '
- X lcall putc
- X inc DPTR
- X inc B
- X mov A, B
- X cjne A, #16, cl_nextbyte
- X lcall putnl
- X mov R0, DPH
- X mov R1, DPL
- X pop B
- X pop DPH
- X pop DPL
- X inc DPTR
- X ajmp next_cmd
- X
- X ; --------------------------------------------------
- Xcmd_notlist: cjne A, #'r', cmd_notread
- X mov A, R3 ; counter
- X push ACC
- X mov A, R1 ; base addr
- X push ACC
- X
- X inc DPTR ; get arg
- X lcall eatspace
- X push DPL
- X lcall hexparse
- X pop ACC
- X cjne A, DPL, nl_loop
- X mov A, #1
- X mov R3, A
- X sjmp nl_start
- Xnl_loop: mov A, R1
- X mov R3, A
- X
- Xnl_start: pop ACC
- X mov R1, A
- X mov A, R1 ; put address
- X lcall putbyte
- X mov A, #':'
- X lcall putc
- X
- Xnl_nextloop: mov A, R3 ; eat one loop
- X jz nl_endloop
- X dec A
- X mov R3, A
- X
- X mov A, #' '
- X lcall putc
- X mov A, @R1 ; put byte
- X lcall putbyte
- X inc R1 ; inc address
- X
- X sjmp nl_nextloop
- X
- Xnl_endloop: lcall putnl
- X pop ACC
- X mov R3, A
- X ajmp next_cmd
- X
- X ; --------------------------------------------------
- Xcmd_notread: cjne A, #'w', cmd_notwrite
- X mov A, R3
- X push ACC
- X mov A, R1
- X mov R3, A ; save addr
- X inc DPTR
- X
- Xnr_nextbyte: lcall eatspace
- X movx A, @DPTR
- X jz nr_earlyeol ; [addr] w [EOL]
- X push DPL
- X lcall hexparse ; [addr] w [NONHEX]
- X pop ACC
- X cjne A, DPL, nr_good
- X sjmp nr_earlyeol
- X
- Xnr_good: mov A, R3 ; R1 = value, R3 = addr
- X mov R0, A
- X mov A, R1
- X mov @R0, A
- X ajmp nr_nextbyte
- X
- Xnr_earlyeol: pop ACC
- X mov R3, A
- X ajmp next_cmd
- X
- X ; --------------------------------------------------
- Xcmd_notwrite: cjne A, #';', cmd_notcomment
- X ajmp next_line
- X
- Xcmd_notcomment: push DPL
- X clr A
- X mov R0, A
- X mov R1, A
- X lcall hexparse ; probably addr, see if ptr
- X pop ACC ; moved, else error
- X cjne A, DPL, cmd_more
- X sjmp cmd_error
- X
- X ; --------------------------------------------------
- Xcmd_more:
- X ; debugging
- X ; push DPL
- X ; push DPH
- X ; mov DPTR, #number_msg
- X ; lcall puts
- X ; mov DPH, R0
- X ; mov DPL, R1
- X ; lcall putword
- X ; lcall putnl
- X ; pop DPH
- X ; pop DPL
- X ajmp next_cmd
- X
- Xcmd_error: mov DPTR, #error_msg
- X lcall puts
- X ajmp next_line
- X
- X; -----------------------------------------------------------------------
- Xtitle_msg: .byte "\r\n8031 mon v3.0\r\n", 0
- Xerror_msg: .byte "syntax error\r\n", 0
- Xregs_msg: .byte "DPTR ACC PSW\r\n", 0
- Xhelp_msg: .byte "8031 mon v3.0\r\n"
- X .byte "[addr] : [bytes]\tstore bytes\t"
- X .byte "[addr] g\t\tcall address\r\n"
- X .byte "[addr] l\t\tlist memory\t"
- X .byte "[addr] r [count]\tlist onchip\r\n"
- X .byte "[addr] w [bytes]\tstore onchip\t"
- X .byte "; [comment]\t\tcomment\r\n"
- X .byte "[value] D\t\tstore in DPTR\t"
- X .byte "[value] A\t\tstore in ACC\r\n"
- X .byte "[value] P\t\tstore in PSW\t"
- X .byte "R\t\t\tprint registers\r\n", 0
- X
- X; -----------------------------------------------------------------------
- X; sort of a bss segment
- X; -----------------------------------------------------------------------
- X .org 0x8000
- Xrun_regs: .skip 2 ; DPTR [H/L]
- Xrun_regs_psw: .skip 1 ; PSW
- X .skip 1 ; ACC
- Xlinebuf: .skip 256
- X
- X .end
- END_OF_FILE
- if test 10618 -ne `wc -c <'new.asm'`; then
- echo shar: \"'new.asm'\" unpacked with wrong size!
- fi
- # end of 'new.asm'
- fi
- echo shar: End of shell archive.
- exit 0
-
-